缘起
分布式微服务系统一直以来都是服务端技术比较重要且是高级的技术领域,首先需要肯定的是,所有微服务都是分布式的系统,微服务的架构离不开分布式,他是一种特殊的分布式,换句话说,微服务架构是分布式服务架构的子集, 微服务架构通过更细粒度的服务切分,使得整个系统的迭代速度并行程度更高。 分布式系统的实现有复杂的诸如Map-Reduce,HBase,Dynamo等,也有简单的只是一个rpc服务。当然我们也可以根据这些复杂系统中的核心思想构建出属于我们自己的分布式微服务系统,这样的系统可能更符合你的业务需求,也可以更好的自我维护和自我扩展。
nmid是用go语言实现的轻量级的分布式微服务调度系统,主要有服务调度服务端,服务调用客户端,服务提供工作端。这也是经典的分布式微服务三端模型。早期的类似服务列如gearmand服务。
nmid项目包括:
1.nmid调用系统,nmid客户端,nmid工作端(go语言实现)。 https://github.com/HughNian/nmid
2.nmid客户端,nmid工作端(c语言实现)。https://github.com/HughNian/nmid-c
3nmid php扩展客户端,nmid php扩展工作端 (c语言实现,php使用)。https://github.com/HughNian/nmid-php-ext
nmid介绍
nmid意思为中场指挥官,足球场上的中场就是统领进攻防守的核心。咱们这里是服务程序的调度核心。是微服务调度系统。
1.server目录为nmid微服务调度服务端go实现,采用协程以及管道的异步通信,带有连接池,自有I/O通信协议,msgpack做通信数据格式。
2.worker目录为nmid的工作端go实现,目前也有c语言实现,以及php扩展实现,可以实现golang, php, c等作为工作端,从而实现跨语言平台提供功能服务,目前在另外一个项目。https://github.com/HughNian/nmid-c
3.client目录为nmid的客户端go实现,目前也有c语言实现,以及php扩展实现,可以实现golang, php, c等作为客户端,从而实现跨语言平台调用功能服务,目前在另外一个项目。https://github.com/HughNian/nmid-php-ext
4.run目录为demo运行目录。为go实现的客户端示例,调度服务端示例,客户端示例。目前调度服务端只有golang的实现。
nmid的工作流
建议配置
cat /proc/version
Linux version 3.10.0-957.21.3.el7.x86_64 ...(centos7)
go version
go1.12.5 linux/amd64
gcc --version
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36)
cmake --version
cmake version 3.11.4
编译安装步骤
git clone https://github.com/HughNian/nmid.git
1.client
cd nmid/run/client
make
2.server
cd nmid/run/server
make
3.worker
cd nmid/run/worker
make
nmid-c介绍
nmid-c是nmid微服务调度系统的客户端和工作端的C语言实现。同时可以编译成C动态库,在其他C程序中调用。nmid-php-ext作为php的扩展就是用了nmid-c项目的动态库。
1.client目录为客户端C语言源码目录,采用libev用作网络库,nmid的自有I/O通信协议,msgpack作为通信数据格式
2.worker目录为工作端C语言源码目录,采用libev用作网络库,nmid的自有I/O通信协议,msgpack作为通信数据格式
3.run目录为客户端,工作端C程序的可执行文件,可执行文件的编译用的是make
4.build目录为客户端,工作端C程序的动态库目录,动态库的编译用的是cmake
建议配置
cat /proc/version
Linux version 3.10.0-957.21.3.el7.x86_64 ...(centos7)
go version
go1.12.5 linux/amd64
gcc --version
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36)
cmake --version
cmake version 3.11.4
需要的库
-lpthread, -lev, -lmsgpackc
编译安装步骤
https://github.com/HughNian/nmid-c.git
1.client可执行文件
cd nmid-c/run/client
make
2.client动态库
cd nmid-c/build/client
里面有之前编译好的动态库,可以把它们都删掉,然后重新编译
cmake ../../client
make
make install
3.worker可执行文件
cd nmid-c/run/worker
make
4.worker动态库
cd nmid-c/build/worker
里面有之前编译好的动态库,可以把它们都删掉,然后重新编译
cmake ../../worker
make
make install
nmid-php-ext介绍
nmid-php-ext是nmid微服务调度系统的客户端和工作端的php扩展实现。采用的是nmid-c的C动态库。目前client和worker是两个独立的扩展装入php中的,后期会合并成一个扩展。
1.clientext目录为客户端php扩展源码目录,主要用到nmid-c的客户端动态库
2.workerext目录为工作端php扩展源码目录,主要用到nmid-c的工作端动态库
建议配置
cat /proc/version
Linux version 3.10.0-957.21.3.el7.x86_64 ...(centos7)
目前只支持linux环境
php --version
PHP 7.3.5 (cli) ( NTS )
注意这里是NTS版的php,目前nmid-php-ext支持php7.3及以上NTS非线程安全版php,不支持ZTS线程安全版php。
go version
go1.12.5 linux/amd64
gcc --version
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36)
cmake --version
cmake version 3.11.4
编译安装步骤
首先需要安装msgpack php扩展。
git clone https://github.com/HughNian/nmid-php-ext.git
1.client扩展
cd nmid-php-ext/clientext
phpize
./configure --with-php-config=/usr/local/php/bin/php-config //这个路径根据自己情况填写
make
make test //可不执行
make install
2.worker扩展
cd nmid-php-ext/workerext
phpize
./configure --with-php-config=/usr/local/php/bin/php-config //这个路径根据自己情况填写
make
make test //可不执行
make install
最后在php.ini文件中加入这两个扩展
I/O的通信协议
-
包结构
1.包头:链接类型[uint32/4字节]+数据类型[uint32/4字节]+包体长度[uint32/4字节]
连接类型:0初始,1服务端server,2工作端worker,3客户端client。 数据类型: server数据请求,server数据返回,worker数据请求...。 包体长度:具体返回包体数据内容的总长度。
2.包体:
(1)client => sever: 客户端请求服务端 包体长度 = UINT32_SIZE + HandleLen + UINT32_SIZE + ParamsLen 方法名长度值空间+方法名长度空间+msgpack后参数长度值空间+msgpack后参数长度空间 包体包含 = 方法长度值+方法名称+msgpack后参数长度值+msgpack后的参数值 client请求参数数据:参数都为字符串数组,入参为 []string{"order_sn:MBO993889253", "order_type:4"},xx:xxx形式,以:分隔 类似key:value。 (2)server => worker: 服务端请求工作端 包体长度 = UINT32_SIZE + HandleLen + UINT32_SIZE + ParamsLen 方法名长度值空间+方法名长度空间+msgpack后参数长度值空间+msgpack后参数长度空间 包体包含 = 方法长度值+msgpack后参数长度值+方法名称+msgpack后的参数值 server请求参数数据:参数都为字符串数组,入参为 []string{"order_sn:MBO993889253", "order_type:4"},xx:xxx形式,以:分隔 类似key:value。可以理解为server做了client的透传。 (3)worker => server: 工作端返回数据服务端 包体长度 = UINT32_SIZE + HandleLen + UINT32_SIZE + ParamsLen + UINT32_SIZE + RetLen 方法名长度值空间+方法名长度空间+msgpack后参数长度值空间+msgpack后参数长度空间+msgpack后结果长度值空间+msgpack后结果长度空间 包体包含 = 方法长度值+方法名称+msgpack后参数长度值+msgpack后的参数值+msgpack后结果长度值+msgpack后结果值 worker返回结果数据:返回数据为统一格式结构体 type RetStruct struct { Code int Msg string Data []byte } (4)server => client: 服务端返回数据客户端 包体长度 = UINT32_SIZE + HandleLen + UINT32_SIZE + ParamsLen + UINT32_SIZE + RetLen 方法名长度值空间+方法名长度空间+msgpack后参数长度值空间+msgpack后参数长度空间+msgpack后结果长度值空间+msgpack后结果长度空间 包体包含 = 方法长度值+msgpack后参数长度值+msgpack后结果长度值+方法名称+msgpack后的参数值+msgpack后结果值 worker返回结果数据:返回数据为统一格式结构体 type RetStruct struct { Code int Msg string Data []byte } 可以理解为server做了worker的透传。