设为首页 收藏本站
查看: 1593|回复: 0

[经验分享] Android和Docker的一致架构设计(3):建立核心集装箱

[复制链接]

尚未签到

发表于 2015-4-17 10:26:19 | 显示全部楼层 |阅读模式
  AndroidDocker一致架构设计(3)
-- 建立企业主的

  By 高焕堂 (台灣Docker論壇 主席)
  misoo.tw@qq.com  2015/03/05
  
  高煥堂的相關文章:
  A01、从「集装箱」思考Docker风潮:Docker潮流下的赢家策略
  A02、Docker:从容到集装箱设计之
  B01、Android和Docker的一致架构设计(1):追求今天决策的未来性
  B02、Android和Docker的一致架构设计(2):包装的通信协议
  B04、Android和Docker的一致架构设计(4):的设计模式
  
前言
     在需求、数据和软件愈来愈碎片化的趋势下,集装箱包装了微服务(Micro-Service)成为主流。这些微服务在运行时间(Run-time)经常需要动态性组合成为各式各样的App来支撑企业多变的业务流程(Business Process)。在本文里,就拿上述的<动态组合>需求为例,展示企业App层的<核心集装箱>的角色。为了促进<端与云>架构设计概念的一致性,本文一方面借镜于Android核心进程(即SystemServe)的设计和角色;一方面运用Docker核心引擎来妥善管理集装箱,可迅速替各企业主设计出其独特的核心集装箱,来协助创造业务App模块之间,极为迅速的、瞬间的动态组合,来支撑企业流程和活动。     

  • Android终端的服务厂商,很可能成为Docker平台最活耀的业主。
  • Android终端用户群,将成为Docker集装箱服务的主要消费群体。         
  其实,业务App模块之间的动态组合,只是本文的应用范例而已。本文的真正目的是要藉这应用范例来呈现出企业主<核心集装箱>的角色和意义。并将Android平台的核心进程概念引用进来,落实为Docker集装箱,也创造<Android + Docker>一致性的端&云整合架构,迈向一致、整体的美感。

1、简介<动态组合>范例
  Linux操作系统有它的核心,称为Linux Kernel。而Docker也有它的核心,称为Docker Engine。
    DSC0000.png
    图-1、两个基础平台的核心
同样地,在云平台上,各企业主也都可以建立一个自己的核心集装箱。
    DSC0001.png
    图-2、替企业建立它的核心集装箱
  于是,形成一个<三合一>的企业云平台核心。
    DSC0002.png       
     图-3、形成三合一的核心架构
 其中,Docker核心的主要任务是管理集装箱的布署信息。例如,掌握集装箱(镜像)之间的相依性(Dependency)。而企业云核心则掌管集装箱内部App的业务模块(Business Module)之间的相依性,以及它们之间的动态性组合(Dynamic Composition)。 举例来说,在游戏业务里,有三个业务模块,分别由不同团队开发,并各自打包成为Docker集装箱,如下图:
   DSC0003.png
   图-4、一款游戏里的三个模块
 在这个游戏里,玩家操控飞机,携带摄像头(Camera)飞越港口上空,游戏画面会出现摄像头所拍到的景象。如下图:
   DSC0004.png
   图-5、飞到港口上空所拍摄到的景象
 这三项企业模块之间的动态結合(Association)关系,并非布署时间(Deployment-time)的相依性,並不属于Docker核心所掌管的范围。当飞机继续飞到另一个城市上空时,将会动态結合另一个集装箱的<城市3D图>,飞机所携带的摄像头会拍到新的城市景象。如下图:
  
   DSC0005.png
   图-6、飞到另一个城市上空所拍摄到的景象
 顾名思义,”Docker”是:码头上的集装箱搬运工。Docker不仅要把集装箱搬运到不同平台(码头),还要搭配业务模块的动态组合而及时建立或删除集装箱,例如,飞机即将到某个城市上空之前,必须及时将<城市3D图>集装箱建立起来;此外,也可能立即将<港口3D图>集装箱删除了。这意味着,在App执行期间(Run-time)可能些业务模块必须及时将最新状态通知Docker Engine核心。但是,又不能让各业务模块开发者都随意使用Docker Engine的API,以避免各业务模块里处处充斥着Docker API,业务模块才不会被Docker绑住。
 于是,有必要特别建立一个业务模块的核心集装箱,内含各种管理型的软件模块,如App Manager模块。
       DSC0006.png            
       图-7、业务层的核心集装箱
   由它来统一负责与Docker核心的通信与合作。

2设计一个业务层的
     兹回忆一下之前的文章:AndroidDocker的一致架构设计:追求今天决策的未来性》,曾经说明了如何降低集装箱之间的相依性,以便创造出具有高度弹性的系统架构。例如下图:
    DSC0007.png
    图-8、如何提升A的复用性?
  其中的A集装箱与B1、B2、B3等诸多集装箱之间,可做动态性的组合。
    DSC0008.png
    图-9、与B的动态组合可提升A的复用性
  我在之前的文章:AndroidDocker的一致架构设计:追求今天决策的未来性》里,借镜于Android而设计一个具有高度未来性的设计,如下图:
    DSC0009.png
    图-10、动态组合的基本架构
  基于这项设计,能创造各式各样的组合关系。如下图:
    DSC00010.png
    图-11、动态创建形形色色的组合
   在动态组合的情境中,这些B1、B2、B3等诸多集装箱,并非事先就全部创建完成的,而是需要使用到的时候,才动态创建的。如下图,在Run-time动态创建了B集装箱,然后才能去调用它内部的App服务。
    DSC00011.png
    图-12、也常动态创建Docker集装箱
  在C集装箱里的绿色模块担任了的角色,是合理的。但是它必须情求Docker Engine来协助创建(Build)这个B集装箱。然后才能去调用B集装箱内部的App服务。如下图:
    DSC00012.png
    图-13、绿色模块(组合者)请求Docker Engine来协助
  表面上看来,上图里的设计是合理的。其实不然,因为Docker Engine的API相关代码会被写在C集装箱的绿色模块里。导致C集装箱与Docker Engine的API产生高度的相依性(Dependency),不是一项有效的(有未来性的)美好设计!!
    DSC00013.png
    图-14、但却让绿色模块高度依赖于Docker Engine的API
  此时,就设计出一个新的,让它负责与Docker Engine通信的任务,有效降低其他各集装箱与Docker Engine的相依性,大幅提升企业软件的跨平台(如Docker平台)的能力。如下图:
    DSC00014.png
    图-15、将Docker Engine的API相关代码移出绿色模块
  这种效益,随着企业的业务模块的成长,会显得更加亮丽。例如下图里,C集装箱内部的业务模块成长了、变复杂了,却完全被Docker集装箱隔离了,让C集装箱具有极高度的跨平台性,更加实践了Docker集装箱的无限美意。不仅仅跨越OS操作系统平台,更能跨越Docker集装箱平台。
    DSC00015.png
   图-16、各个组合模块皆独立于Docker Engine的API
   一般而言,企业主在云平台上,只需要一个像M这种,所以当Docker Engine的API改版了,或Docker Engine被抽换掉了,只需要改写M集装箱里的红色模块而已,非常简单容易。这个M就通称为企业主的。

3、观摩Android架构设计
3.1 基本架构
Linux平台有其核心(即Linux Kernel),而Docker平台也有其核心(即Docker Engine)。一样地,Android平台也有其核心(即SystemServer)。在本节哩,就来借镜于Android核心进程(Process),来引导我们思考如何设计各企业主的云平台核心集装箱。在Android平台哩,SystemServer进程就扮演着Android平台的核心角色。如下图:
    DSC00016.png
     图-17、SystemServer是Android的核心进程
  在Android里,Activity主要是提供UI画面的布局(Layout)与设计,来支持人机交互的需要。在这人机交互的过程中,Activity常常需要动态地去启动一个或多个Service。而Service主要是提供幕后的服务,例如播放游戏的背景音乐、从网络上下载图片或影片等任务。这些Activity和Service经常是由不同的团队分别开发、并在不同的进程里执行。举例来说,在Run-time期间,当上图里myActivity需要去调用myService的服务时,就会发出bindService信息给SystemServer进程里的AMS(即ActivityManagerService)模块,目的是去绑定myService。此时,这个myService的进程可能尚未创建,也可能已经存在了。如果,还不存在的话,AMS就会透过Zygote进程来发出信息给Linux Kernel,要求创建一个新进程。如下图:
    DSC00017.png
    图-18、AMS发出信息给Linux Kernel
Linux Kernel接到AMS的请求之后,它就去创建一个新的进程,并且把Service的代码载入(Load)到这个新进程里。如下图:
    DSC00018.png
     图-19、Linux Kernel创建一个新进程
 然后,AMS就要求Service进程的myService模块,回传IBinder接口。这过程就通称为:绑定(Bind)了myService。其目的是要建立myActivity与myService之间的联结(Connection)。AMS取得myService的IBinder接口之后,就回调(Callback)这myActivity模块,把IBinder接口递交给myActivity,就完成了绑定myService的任务了。也就是myActivity成功地建立了与myService之间的联结了。
    DSC00019.png
     图-20、myActivity绑定了myService
  一旦取得myService的IBinder接口,myActivity就能透过IBinder接口而调用myService的服务了。如下图:
    DSC00020.png
      图-21、myActivity调用myService的服务
   关于App软件的进程都是由AMS来掌握,如果需要新的进程,AMS就会透过Zygote要求Linux Kernel来创建。所以SystemServer就扮演Android平台的核心角色,而AMS是SystemServer进程里的重要模块之一。我们可以看到,无论是Docker或Android平台架构里都有其核心进程(集装箱)。在云平台上,可借镜于Android架构,也设计出企业主的核心进程(集装箱),将是非常有帮助的。

3.2 Android的应用程序代码
  兹建立Android开发项目:
     DSC00021.png
    此程序的执行画面如下:
     DSC00022.png
    其源代码如下:
  // myActivity.java
package com.misoo.pk01;
  public class myActivity extends Activity implements OnClickListener {
   //………
   public void onCreate(Bundle icicle) {
     //………
     bindService(new Intent("com.misoo.pk01.REMOTE_SERVICE"), mConnection, Context.BIND_AUTO_CREATE);
   }
   private ServiceConnection mConnection = new ServiceConnection() {
     @Override
       public void onServiceConnected(ComponentName className, IBinder ibinder) {
       ib = ibinder;
     }
     };
   public void onClick(View v) {
      // ………
      ib.transact(1, data, reply, 0);
      // ………
}}
  // myService.java
public class myService extends Service implements Runnable {
   // ……….
   @Override public void onCreate() {
      super.onCreate();
      mBinder = new myBinder();
    }
   @Override public IBinder onBind(Intent intent) {
      return mBinder;
}}
  // myBinder.java
package com.misoo.pk01;
// ........
public class myBinder extends Binder{
   @Override
   public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
   // …….
   myService.h.sendMessage(msg);
   // ……
}}

    兹说明上述的软件程序,首先看代码:
     bindService(new Intent("com.misoo.pk01.REMOTE_SERVICE"), mConnection, Context.BIND_AUTO_CREATE);
     就是myActivity调用父类Activity的bindService()函数,然后由Activity转而调用AMS的bindService()函数。这就是上图-18所呈现的情形。接着,如果需要创建新的进程,AMS就会透过Zygote要求Linux Kernel创建一个新进程。这就是上图-19所呈现的情形。 此时,有了myService进程,AMS就访问这个myService进程,转而执行到myService模块的onCraete()和onBind()函数,这段代码就是:
     @Override public void onCreate() {
      mBinder = new myBinder();
    }
   @Override public IBinder onBind(Intent intent) {
      return mBinder;
    }
  其中,onBind()函数就将IBinder接口回给AMS。接着AMS就回调(Callback)到myActivity模块,把IBinder接口地交给myActivity。这项回调的代码如下:
     private ServiceConnection mConnection = new ServiceConnection() {
      @Override
      public void onServiceConnected(ComponentName className, IBinder ibinder) {
         ib = ibinder;
    }};
  这就是上图-20所呈现的情形。此时,myActivity就接到IBinder接口了。myActivity就可调用 IBinder接口的transact()函数。这段代码如下:
     public void onClick(View v) {
      // ………
      ib.transact(1, data, reply, 0);
      // ………
    }
  现在执行到IBinder接口的transact()函数,其转而调用myBinder的onTransact()函数,就执行到代码如下:
   public class myBinder extends Binder{
       @Override 
     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
       // …….
       myService.h.sendMessage(msg);
       // ……
   }}
   = => 请看完整源代码
   这onTransact()就转而调用myService的服务了。当您仔细观察上述Android应用程序代码,统统看不见与AMS、Zygote及Linux Kernel的API接口的相关代码。都是集中并封装于SystemServer的核心集装箱(进程)里。这种优越的架构设计替企业主带来了极大的利益,不仅仅让企业的App模块可以跨OS平台,也能更进一步跨Docker平台。

4、一致的架构:应用于Docker集装箱
   无论是Linux、Docker或Android都各有它自己的核心部分。而且Docker和Android都以进程为沙盒空间(也可称为集装箱),例如,Docker的核心进程是Docker Daemon;而Android的核心进程是SystemServer。基于一致性的架构设计,我们也可以替企业主,在其云平台上建立一个业务层软件的核心。
   从上述Android的平台架构,可以看出来,其核心进程(SystemServer)是蛮复杂的,而且还包装了与底层平台(如Linux Kernel)的API相关代码,所以核心进程的内部(代码)是既复杂又多变。也就是因为它的复杂多变,更需要集装箱的的特质来将它的复杂多变包装起来,呈现出简单的次序。因之,Docker集装箱恰可派上用场,它让我们更能做出好的系统核心,包括企业云平台的核心集装箱。首先从Docker核心(Docker Engine)谈起,如下图:
  DSC00023.png
   图-22、提供三个镜像给Docker Engine
 Docker Engine依据M的镜像(Image)来创建一个M集装箱。它就扮演核心集装箱的角色。如下图:
   DSC00024.png
   图-23、创建了核心集装箱(M)
 在核心集装箱(M)里,可以添加一些<管理型>的软件模块,例如上图里的App Manager模块,担任插件(Plug-in)的管理等任务。此外,未来也可以逐渐添加更多的插件模块。至于这M核心集装箱里该摆入那些模块,就是我们的职责了,就是:依据平台、技术、业务等不同需求或条件限制来考虑,然后设计出来的。通常这种核心进程都是常驻型的集装箱,也算是守护进程(Daemon)。接下来,企业主还可以透过DockerEngine来创建其他的集装箱来跑各式各样的业务App模块。例如,基于A的镜像来建立A集装箱,如下图:
   DSC00025.png
  图-24、创建一个A集装箱
 在A集装箱的执行时(Run-time),如果需要动态性去绑定S集装箱里的myServive服务,就可发送信息给M(核心)集装箱里的App Manager模块,由它来请求Docker Engine创建一个S集装箱,如下图:
DSC00026.png
      图-25、A委托M来创建S集装箱
 然后,AppManager就去绑定S集装箱里的myService服务,并取得myService的接口。这过程就通称为:绑定了myService,如下图。其目的是要让A集装箱建立起与S集装箱的连结联机(Connection),也就是支持两个集装箱之间的动态组合。
DSC00027.png
      图-26、A委托M来绑定Service模块
 App Manager取得myService的接口之后,就回调这绿色模块,把myService的接口递交给绿色模块,就完成了绑定myService的任务了。一旦取得myService的接口,myActivity就能透过该接口而调用myService的服务了。如下图:
DSC00028.png
       图-27、A与S交换信息或数据
  从这图里可看到,目前已经成功建立了A集装箱的绿色模块与S集装箱的myService之间的动态组合。在执行过程中,可能需要再创造一个动态组合,例如在下图里,黄色模块想与Service-x模块进行动态组合。此时,就可透过M核心集装箱里的App Manager来绑定Service-x模块,如下图:
DSC00029.png
      图-28、A和S集装箱内部随着企业需求而变化
   App Manager取得Service-x接口之后,就回调这黄色模块,把Service-x的接口递交给黄色模块,就完成了绑定Service-x的任务了。一旦取得Service-x的接口,黄色模块就能透过该接口而调用Service-x的服务了。如下图:
  DSC00030.png
        图-29、随着企业需求变化而动态组合
  其中,Docker Engine负责管理集装箱本身,而企业主的M核心集装箱则负责建立业务模块之间的关系;两者相辅相成,创造云平台的美好次序(Order)。

5、结语
5.1  <命令流与数据流的分离法则
    软件有两种主要流程:一种是命令流(Commandflow),而另一种是数据流(Data flow)。许多软件人员常常误认为数据流才是最重要的。其实不然,在架构设计上,命令流程的设计更是关键。在我写的《思考软件、创新设计:A段架构师的思考技术》一书的第10章哩,也提出了云平台架构设计的十项法则,其中的第4项就是:命令流与数据流的分离法则。例如,下图里的软件交互调用流程就是命令流。
DSC00031.png
            图-30、命令流之范例
 这图里展现了命令流,它的目的是去建立绿色模块与Service-x之间的连结(Connection) 。以日常生活来比喻,这命令流是用来指挥各模块(如DockerEngine、App Manager)去合作搭建桥梁;而数据流则是让行人或车辆从搭好的桥梁上鱼贯地通过。例如下图:
DSC00032.png
            图-31、数据流之范例
 一般而言,命令流的软件逻辑常常比数据流要复杂许多,所以藉由Docker集装箱来将复杂多变包装起来,发挥了集装箱天赋的<序中有乱>特质,让我在设计企业主的<核心集装箱>时,变得简单许多了。此外,善加利用法则,可带来系统的弹性,并大幅提升数据流的执行效能。例如,控制手机摄像头(Camera)的信息是命令流;而传送预览(Preview)视像的是数据流。命令流指挥数据流,通常可以透过命令流API去通知两端的模块,动态启动两端插件,透过动态API(如Config文件提供)串接两端;静态CommandAPI支撑动态Data API。
       例如,在建置大数据平台时采用Hbase。这Hbase是以Java开发的,其提供了Java基础接口,在C层则使用thrift机制。如果咱们的C层模块想存取Hbase时,使用的技术是:C调用jni,再调用Hbase的Java接口(亦即C->jni->Java),但这种架构方式,会导致性能下降,该如何解决这个议题呢?  这个议题可以将两种流程分离开来。并且厘清数据来原(Data Source)是在C层(可能是先已经从Hbase查询出来,放在C层了)或是在Java层的Hbase里。如果数据来源是在Hbase里,其thrift接口就是合适的数据来源接口。如此,数据来源接口在C层,而Client(即数据目的地)也在C层。于是:

  • Dataflow是C->C,不要经由Java层,效率就极高。
  • Commandflow可以经过Java层,有助于控制点放在Java层。
  • Command flow:C->JNI->Java接口,要求Java模块把Hbase端的C接口传递给Client。这常常在编译时(AtCompile-time)就已经安排的API,通称为静态配置的。此时,Java模块可动态读取Config配置文件,依其指示而把Hbase端的特定C接口(如thriftAPI)传递给Client,这通称为动态配置的。
  • Dataflow: Client就可调用上述动态配置的Hbase的C接口(若跨进程,可透过IBinder接口),进而顺利取得所需的数据。
5.2  带给企业无限活力
    每一台电脑都有(简称Mother-Board),它是IT产业人人都接触过的东西。它是一个集装箱,包容了极多样化的电脑芯片及相关模块。后来,人们就将全世界的电脑主板都连接起来,就成为当今风行的互联网(Internet)了。前面也提过了,在当今的需求和软件碎片化的大数据时代里,一个企业主的业务层App软件常常分布在各式各样不同的工有云或私有云上,我们可以协助众多企业主建立云平台上的核心集装箱,它就像一个电脑的主板,其控制着周边的相关模块。然后,再将这些分布于各云端的核心集装箱连结起来,成为企业主专属的大数据平台。
    基于Docker集装箱的<序中有乱>特质,虽然核心集装箱内部的软件逻辑是复杂多变的,但集装箱的概念和操作接口是很简单的。也因为这项简单之美,带给它无限的生命力,也带给众多企业无限的活力。  
  
  高煥堂的相關文章:
   A01、从「集装箱」思考Docker风潮:Docker潮流下的赢家策略
   A02、Docker:从容到集装箱设计之
   B01、Android和Docker的一致架构设计(1):追求今天决策的未来性
   B02、Android和Docker的一致架构设计(2):包装的通信协议
   B04、Android和Docker的一致架构设计(4):的设计模式
  ~ End ~
  







  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-58067-1-1.html 上篇帖子: Docker实践(5)—资源隔离 下篇帖子: Docker学习总结之docker创建私有仓库(private Repositories)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表