一.服务端为客户端提供哪些功能?
- 服务注册
- 拉取服务列表
- 心跳检查
- 集群服务节点批量复制其他服务节点信息
- 查询实例信息
- 服务器状态复写
- 更新节点信息(续约)
- 更新客户端元数据信息
- 取消续约
这些功能可以在PeerReplicationResource类和其同包下的类中找到,具体如何提供的,下面开始分析具体流程
二.提供方式
1.Eureka与客户端的沟通:Jersey
在Eureka中,是通过Jersey提供Restful接口来为客户端提供服务的
至于Jersey是啥:传送门
2.Jersey在哪里引入
在EurekaServerAutoConfiguration
中注册了Jersey过滤器到servlet容器中,通过过滤器将指定的url交给jersey来处理。
三.Jersey的调用链路解析(感觉自己跑偏了,但是看了那么多不写下来有点浪费)
1.Jersey的请求入口
在上图中我们可以看到,过滤器是通过ServletContainer
实例化的,ServletContainer
又是继承自HttpServlet
和Filter
。
根据Filter原理,我们可以知道doFilter可以决定是否放行,所以我在ServletContainer
打一个断点。
在下图中,拦截的URL标明已经拦截到第三方的请求,并交给service处理
2.谁在进行路由匹配?
一步步向下跟踪,在com.sun.jersey.server.impl.application.WebApplicationImpl#_handleRequest(com.sun.jersey.server.impl.application.WebApplicationContext, com.sun.jersey.spi.container.ContainerRequest)
方法中我们可以看到进行了路由匹配,再往下就结束了,那么整个处理应该就在accept
方法里了。
解析一下accept
方法,看看谁将对这个path
做出下一步处理
public boolean accept(CharSequence path, Object resource, UriRuleContext context) {
//里面是个空方法,暂时不知道有啥用(略过)
UriRuleProbeProvider.ruleAccept(
RootResourceClassesRule.class.getSimpleName(),
path,
resource
);
//打印访问路径
if (context.isTracingEnabled()) {
context.trace("accept root resource classes: \"" + path + "\"");
}
//来了来了,重头戏来了,开始进行规则匹配了(就是url路径匹配)
final Iterator<UriRule> matches = rules.match(path, context);
while(matches.hasNext())
//匹配到对应的UriRule,开始执行accept
if(matches.next().accept(path, resource, context))
return true;
return false;
}
在断点跟踪中,下图可以看到matches.next()
的值为RightHandPathRule
,那么继续跟踪RightHandPathRule
的accept
方法
3.来自Rule的循环accept
来自RightHandPathRule
的accept
的进一步accept
调用,框架的层层递进是框架的精妙,是调试者的灵魂拷问
由于路径匹配的规则,会进行一层层的递进匹配:/eureka/peerreplication/batch/
1.先用RootResourceClassesRule
匹配出peerreplication
是在哪个类中,类似于SpringMVC中匹配Controller。
2.交给RightHandPathRule继续匹配`/batch/` ,并记录匹配情况,然后调用ResourceClassRule的accept
3.然后通过`ResourceClassRule`来加载匹配到的`PeerReplicationResource`类,并向下传递给RightHandPathRule进行进一步匹配
4.RightHandPathRule继续向右解析,进入HttpMethodRule进行方法调用(如果最后一个是参数的话,那么就先进入`SubLocatorRule` 进行初始化子类资源,再进入HttpMethodRule方法)
5.在HttpMethodRule中,通过`method.getDispatcher().dispatch(resource, context)` 进行转发,然后经过一系列的反射操作,到达PeerReplicationResource类中
6.最终我们来到了`PeerReplicationResource`的`batchReplication`方法,在`PeerReplicationResource`上用`Path`注解中有值`/{version}/peerreplication` ,在`batchReplication`方法上`Path`注解中有值为batch,刚好与我们`/eureka/peerreplication/batch/` 路径进行匹配,由此可知,这个类就是接受客户端请求的处理类。
三.结语
进入PeerReplicationResource
后,我们也就知道了,服务端提供了哪些接口,并有些什么功能。在这个过程中,我顺便讲解了一下jersey的URL匹配流程。在PeerReplicationResource
的同包下还有很多同样的Resource类,里面提供了Eureka的诸多服务接口。这章到此结束,下一节我们来看看服务端是如何将客户端添加到注册列表中的。