前言
SpringCloud微服务架构这几年已经使用非常广泛了,如下图是目前大多公司使用的基础业务架构图,通过围绕SpringCloud这个架构核心来做的各种部署和设计
但是随着业务量的增加,和部门团队的多样化,很多业务我们可能使用python或者golang实现从而更方便或者效率更高。比如国内某滴公司或者其他一些公司会使用到一些地图类的搜索算法,而这些算法大多使用python语言来做实现开源。
因此有上面这个例子引出我们这篇文章的思考,如何把python实现的微服务或者golang实现的微服务联合起我们已经的服务架构里,以实现更好的服务实现和平滑的访问切换,客户端无感知的状态
解决方案
Nginx反向代理实现
通过我们对基础架构图的了解来看实现结合多种语言来实现微服务的架构,比较简单的一种方案是通过nginx来配置反向代理实现,访问不同的语言的架构服务。设计图如下
这种设计的优点比较明显的就是不用考虑其他语言实现的微服务,直接通过nginx的配置,访问到对应的服务上;缺点是需要单独的配置不同的二级域名的访问,而且对于微服务的治理这块就是一块缺失的。因为这种方案的实现比较简单这里就不做过多介绍,虽然简单但是确实最可靠的一种方案。不会出现很多幺蛾子。
注册其他语言微服务到SpringCloud注册中心
第二种方案实现的架构图如下,也就是需要把其他语言实现的微服务加入到erueka的注册中心治理中,如果实现了这样的服务架构,那么对于客户端来说就是无感知的。对于服务端来说也是比较友好的。不同的团队或者个人负责不同的微服务的维护,同时兼容了个人掌握的技能,真正实现技能的充分发挥
但是实现这样架构的前提是,不同语言需要维护其对于注册中心的注册以及心跳的检测等逻辑,而且每个注册中心都有自己不同的协议,如果开发过程更换注册中心的话,这一项也是一个需要考虑的点。不过现在一般轮子各路大神都已经造好, 切换起来成本也不是很高。具体参考下面实现部分
特别注意的是这里探讨的技术实现目前还是处于实验阶段,虽然能建立如上图所示的基础架构,但是没有完全使用在生成环境中,生成环境最靠谱的做法还是第一种架构设计
Erueka客户端实现原理
erueka客户端的实现,通过java的源码可发现其主要是通过http协议和注册中心REST请求通讯从而维护了一套客户端注册,心跳,断开等场景处理
com.netflix.discovery.DiscoveryClient
java 核心实现在这里
- 注册客户端信息
POST /eureka/apps/{APP_NAME}
{
"instance":{
"instanceId":"192.168.1.107:golang-example:10000",
"hostName":"192.168.1.107",
"ipAddr":"192.168.1.107",
"app":"golang-example",
"port":{
"@enabled":"true",
"$":10000
},
"securePort":{
"@enabled":"true",
"$":443
},
"status":"UP",
"overriddenStatus":"UNKNOWN",
"dataCenterInfo":{
"name":"MyOwn",
"@class":"com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo"
}
}
}
- 心跳
心跳主要的目的就是维护注册中心持续的关注此客户端,否则一段时间注册中心收不到来自客户端的心跳请求的时候就会默认删除对此客户端的维护
PUT /eureka/apps/{APP_NAME}/{INSTANCE_ID}?status=UP&lastDirtyTimestamp={TIMESTAMP}
- 获取已注册的服务列表
GET /eureka/apps
或者/eureka/apps/delta
前者获取全部的已注册的服务信息,后者则是获取增量的一些注册信息。
<application>
<name>GOMOUDLE</name>
<instance>
<instanceId>192.168.0.22:gomoudle:8506</instanceId