前言
公司近期要将园区所有的服务做成微服务模式,因之前负责的网关服务是C++来实现的,因此研究了一下非jvm语言实现向Eureka注册中心注册的过程,特此记录,以便后续的温习,初次了解微服务,如有错误,欢迎指正。
关于sidecar模式的原理和为何采用sidecar模式在网上能够找到相关的博客去了解,这里转载几篇好的文章,大家可以学习了解一下。
https://blog.csdn.net/StarskyBoy/article/details/85012642
https://blog.csdn.net/yang00322/article/details/77964703
https://www.jianshu.com/p/a96056870143
流程
下面主要来记录一下服务和Eureka注册中心交互的过程,以下的过程是根据java的同事在通过配置Eureka客户端,来向Eureka服务器发起请求时,用wireshark抓包工具查看完整的交互流程。再通过Eureka提供的REST接口,利用C++里面的Poco库的http相关接口,来实现微服务化向Eureka注册,并实现服务的监控。
1、服务注册
REST接口:POST /eureka/v2/apps/appID
代码段如下:
Poco::URI uri("http://ip:port/eureka/apps/appID");
Poco::Net::HTTPClientSession session(uri.getHost(), uri.getPort());
session.setKeepAlive(true);
//创建 HTTP request
Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_PUT, uri.getPathAndQuery(), Poco::Net::HTTPMessage::HTTP_1_1);
request.setContentType("application/json; charset=utf-8");
request.setContentLength((int)msg.length());
std::ostream &reqOstr = session.sendRequest(request);
reqOstr << msg;
其中,appID是要向Eureka注册的服务名,msg是一个标准的json字符串,json字符串的基本内容如下图:
*以下是我整理的注册发给Eureka的json字符串的相关字段释义:
InstanceInfo服务实例信息字段:
1)instanceId : 实例id
2)hostName: 主机名称
3)app:应用名
4)ipAddr:ip地址
5)status:实例状态,如UP,DOWN,STARTING,OUT_OF_SERVICE,UNKOWN
6)overriddenStatus:外界需要强制覆盖的状态值,默认为UNKOWN
7)port:端口号
8)securePort:https的端口号
9)countryId:被废弃的属性,属性为1,代表US
10)dataCenterInfo:dataCenter的信息,Netflix或者Amazon或者MyOwn
11)leaseInfo:租约信息
12)metadata:应用实例的元数据信息
13)homePageUrl:应用实例的首页url
14)statusPageUrl:应用实例的状态页
15)healthCheckUrl;应用实例的健康检查url
16)vipAddress:虚拟ip地址
17)secureVipAddress:https的虚拟ip地址
18)isCoordinatingDiscoveryServer:首先标识是否是DiscoveryServer,其次标识该DiscoveryServer是否是响应你请求的实例
19)lastUpdatedTimestamp:状态信息最后更新时间
20)lastDirtyTimestamp:实例信息最新的过期时间,在client端用于标识
21)sid:被废弃的属性,默认为na
22)actionType:标识EurekaServer对该实例执行的操作,包括ADDED,MODIFIED,DELETE这三类
23)asgName:在AWS的autoscaling group的名称
LeaseInfo租约信息字段:
以下参数主要用于标识应用实例的心跳情况,比如约定的心跳周期,租约有效期,最后一次续约时间等。
1)renewalIntervalInSecs:client端续约的间隔时间
2)durationInSecs:client端需要设定的租约的有效时长
3)registrationTimestamp: Server端设置的该租约第一次注册时间
4)lastRenewalTimestamp: Server端设置的该租约最后一次续约时间
5)evictionTimestamp;Server端设置的该租约被剔除的时间
6)serviceUpTimestamp:Server端设置的该服务实例标记为Up的时间*
2、获取服务实例
获取服务实例的接口有两个,一个是获取全量服务实例列表,即每次获取Eureka服务器上的所有实例,另外一个是实现增量实例列表,增量拉取变化的服务信息,然后本地去做更新。
REST接口:
全量:GET /eureka/apps
增量:GET /eureka/apps/delta
这里为了方便只是做了全量的实现,代码段如下:
Poco::URI uri("http://ip:port/eureka/apps");
Poco::Net::HTTPClientSession session(uri.getHost(), uri.getPort());
Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, uri.getPathAndQuery());
session.sendRequest(request);
这里通过抓包来分析,只有第一次调用的是全量的接口,后面每次发送心跳后都会调用一次获取增量的接口,来做本地服务实例的更新。
3、心跳检测/心跳续约
注册完之后,会根据配置的心跳时间来规律的向Eureka发送心跳,告诉它还“活着”,如果超过续约时间还没有发接收到心跳,Eureka服务端会将服务自动剔除。这个时间间隔是可配的,上面字段释义里面已经提到。
REST接口:PUT /eureka/apps/appID/instanceID
(instanceId是和服务实例相关联的唯一id,默认组成为hostname+appId+端口号)
代码同注册的代码段,只需要将http的请求方式post改成put即可。
4、服务下线
服务下线,当服务主动停止后,会触发一个服务下线的REST请求,告诉Eureka下线,此时Eureka会将服务设置为DWON,并将消息广播发送出去,并更新缓存清单。
REST接口:DELETE/eureka/apps/appId/instanceId
5、健康检查
服务微服务化之后,会对里面的业务进行自我监控,如果某个业务断开连接或者不正常工作,就需要发送给Eureka注册中心,将服务的状态从UP改为DOWN,Eureka注册中心就不会再向客户端发起请求,这样的一个流程就叫做健康检测。健康状态接口还可以通过http://ip:port/health来查看,内容如下:
Example:
{
"description":" Eureka Client",
"status":"UP"
}
总结
整个流程下来其实不难,我理解的是这样,sidecar模式其实也是在本身存在的服务基础上实现一个健康检查接口,向Eureka服务端注册,并向Eureka服务端反馈自身的一个健康情况。
第一次写博客,如有错误或者不当的地方,欢迎指正!如果有侵权的地方,请及时告知,谢谢!