1, 前言
分布式已经成为了当前最热门的话题, 分布式框架也百花齐放, 群雄逐鹿. 从中心化服务治理框架, 到去中心化分布式服务框架, 再到分布式微服务引擎, 这都是通过技术不断积累改进而形成的结果. esb, 网关, nginx 网关 这些中心化服务治理框架现在都是各个公司比较主流的架构, 而最近几年大家炒的比较火的去中心化微服务框架, 各个语言都有其代表作品, 比如. NET 就有 orleans,akka.net, 这些框架不言而喻都能从网上了解一二, 但是针对于这些框架, 是不是就满足公司的需要, 就能搭建起整个平台呢?
可以告诉大家, 下一代框架应该称为分布式微服务引擎, 也可以叫做服务网格, 它应该是基础设施引擎, 加载驱动业务模块服务, 负责服务之间的可靠传递, 提供了所需的网络协议, 而针对 surging 服务引擎就是朝着这个思想前进, 内部通过 RPC 进行调用, 有一套完整的服务治理规则, 提供了 tcp,http,ws 协议, 并且可以支持容器化, 可定制化引擎部署, 下面我们来看看是如何实现的.
2. 服务引擎
服务引擎是用于处理服务与服务可靠通信的专用基础设施. 而服务应该是独立进行部署的, 无需寄宿在其它框架当中, 由于服务之间的独立性, 业务团队不再需要操心服务治理相关的复杂度, 全权交给服务引擎处理即可. 针对每一个服务实例, 服务引擎都会在同一主机上一对一并行部署一个服务进程, 实现该服务实例所有对外的网络通讯 (参见下图), 借助于良好的框架封装, 运维成本也可以得到有效的控制.
2.1 演化史
surging 从无到有可分为三个演化阶段
第一个阶段 RPC 服务治理框架, 服务与服务之间通信通过接口创建代理的方式进行访问
第二个阶段 RPC 服务治理框架 + 网关, 服务与服务之间通信通过接口创建代理或 RoutePath 进行访问, 外部通过网关进行调用
第三个阶段服务引擎, 服务不再关心通讯细节和通信协议, 统统交给引擎, 只需要关注业务的实现
2.2 架构
针对于 surging 现在提供了 tcp,http,ws 三种通信协议, tcp,http 协议是基于 dotnetty https://github.com/Azure/DotNetty , 而 ws 是基于 https://github.com/sta/websocket-sharp 的分支版本 websocketcore(该版本支持. NET CORE)
而整个引擎的架构如下图所示, 通过对外的网络通信协议, 可以对接移动, web, 物联网应用, 通过服务发现 RPC 远程调用内部业务服务.
3. 如何开发基于协议的业务模块
3.1 基于 http,tcp 协议业务接口
继承 IServiceKey, 并且都需要标识 [ServiceBundle("Api/{Service}")], 代码如下
- [ServiceBundle("api/{Service}")]
- public interface IManagerService : IServiceKey
- {
- [Command(Strategy = StrategyType.Injection, ShuntStrategy = AddressSelectorMode.HashAlgorithm, ExecutionTimeoutInMilliseconds = 2500, BreakerRequestVolumeThreshold = 3, Injection = @"return 1;", RequestCacheEnabled = false)]
- Task<string> SayHello(string name);
- }
3.2 基于 ws 协议业务接口
继承 IServiceKey, 并且都需要标识 [ServiceBundle("Api/{Service}")],ws 服务与服务之间的远程调用, 需要把负载分流设置为哈希算法代码如下
- [ServiceBundle("Api/{Service}")]
- public interface IChatService: IServiceKey
- {
- [Command( ShuntStrategy=AddressSelectorMode.HashAlgorithm)]
- Task SendMessage(string name,string data);
- }
3.3 基于 http,tcp 协议业务实现
继承 ProxyServiceBase 和业务接口 IManagerService
- public class ManagerService : ProxyServiceBase, IManagerService
- {
- public Task<string> SayHello(string name)
- {
- return Task.FromResult($"{name} say:hello");
- }
- }
3.4 基于 ws 协议业务实现
继承 WSServiceBase 和业务接口 IChatService, 注意: ws 服务之间的调用只能通过基于 routepath 远程调用, 不支持通过接口创建代理远程调用
- public class ChatService : WSServiceBase, IChatService
- {
- private static readonly ConcurrentDictionary<string, string> _users = new ConcurrentDictionary<string, string>();
- private static readonly ConcurrentDictionary<string, string> _clients = new ConcurrentDictionary<string, string>();
- private string _name;
- protected override void OnMessage(MessageEventArgs e)
- {
- if (_clients.ContainsKey(ID))
- {
- Dictionary<string, object> model = new Dictionary<string, object>();
- model.Add("name", _clients[ID]);
- model.Add("data", e.Data);
- var result = ServiceLocator.GetService<IServiceProxyProvider>()
- .Invoke<object>(model, "api/chat/SendMessage").Result;
- }
- }
- protected override void OnOpen()
- {
- _name = Context.QueryString["name"];
- if (!string.IsNullOrEmpty(_name))
- {
- _clients[ID] = _name;
- _users[_name] = ID;
- }
- }
- public Task SendMessage(string name, string data)
- {
- if (_users.ContainsKey(name))
- {
- this.GetClient().SendTo($"hello,{name},{data}", _users[name]);
- }
- return Task.CompletedTask;
- }
- }
3.5. 提供哈希分流选址接口
通过调用内部提供的哈希分流选址接口, 就可以把传递同一参数 KEY 分配到同一个服务提供者上.
3.6 基于 WS 协议测试
4. 容器化部署
通过 docker 下载 surging 引擎, 现在的版本是 v0.8.0.2
docker pull serviceengine/surging:v0.8.0.2
启动 surging 引擎
docker run --name surging --env Mapping_ip=192.168.249.242 --env Mapping_Port=93 --env RootPath=/home/fanly --env Register_Conn=192.168.249.162:8500 --env EventBusConnection=192.168.249.162 --env Surging_Server_IP=0.0.0.0 --env Surging_Server_Port=93 -v /home/fanly:/home/fanly -it -p 93:93 surging
运行如下图所示:
环境变量
Protocol: 可以设置 Http,Tcp,WS,None, 其中设置 Http,Tcp,WS 表示仅支持相关协议, None 表示可以支持所有协议
RootPath: 业务模块存储的根目录, 如:/home/fanly
HttpPort: 启动 Http 协议主机端口
WSPort: 启动 WS 协议主机端口
UseEngineParts: 设置启用的服务引擎组件, 默认是 DotNettyModule;NLogModule;MessagePackModule;ConsulModule;HttpProtocolModule;EventBusRabbitMQModule;WSProtocolModule;(注意: 如果是 nuget 定制化引擎, 不需要配置 Packages, 可以进行删除, 只需下载所需的引擎组件, 会自动装配注册到服务引擎)
IP: 私有容器 IP, 一般都是设置 0.0.0.0
Server_Port: 私有容器端口
Mapping_ip: 公开主机 IP
Mapping_Port: 公开主机端口
5. 总结
surging 研发已经过去一年, 从原来只支持 RPC 远程服务访问, 到现在可以支持容器化部署, 支持 tcp,http,ws 协议的服务引擎, 其中的成长演化非常有意思, 有很多灵感只有在开发的时候才会灵光乍现, 也希望以后能有更好的设计思想融入到 surging 中, 也同时希望 surging 越来越强大.
来源: https://www.cnblogs.com/fanliang11/p/9314469.html