在上一片中 我们已经知道注册、更新、拉服务所发送的接口,那么现在就直接在服务端搜索这个接口,找到了类
ApplicationsResource 有对这种请求不了解的请看 我的前面的 ServletContainer源码分析
ServletContainer源码分析
入口类ApplicationsResource
@Path("/{version}/apps")
@Produces({"application/xml", "application/json"})
public class ApplicationsResource {
//注册和更新状态走这
@Path("{appId}")
public ApplicationResource getApplicationResource(){}
//得到全部服务走着 不管有没有效 走这
@GET
public Response getContainers(@PathParam("version") String version,
@HeaderParam(HEADER_ACCEPT) String acceptHeader,
@HeaderParam(HEADER_ACCEPT_ENCODING) String acceptEncoding,
@HeaderParam(EurekaAccept.HTTP_X_EUREKA_ACCEPT) String eurekaAccept,
@Context UriInfo uriInfo,
@Nullable @QueryParam("regions") String regionsStr) {}
//得到有效的服务
@Path("delta")
@GET
public Response getContainerDifferential(
@PathParam("version") String version,
@HeaderParam(HEADER_ACCEPT) String acceptHeader,
@HeaderParam(HEADER_ACCEPT_ENCODING) String acceptEncoding,
@HeaderParam(EurekaAccept.HTTP_X_EUREKA_ACCEPT) String eurekaAccept,
@Context UriInfo uriInfo, @Nullable @QueryParam("regions") String regionsStr) {
}
}
注册与刷新状态ApplicationResource
@Produces({"application/xml", "application/json"})
public class ApplicationResource {
@GET
public Response getApplication(@PathParam("version") String version,
@HeaderParam("Accept") final String acceptHeader,
@HeaderParam(EurekaAccept.HTTP_X_EUREKA_ACCEPT) String eurekaAccept) {}
//刷新状态
@Path("{id}")
public InstanceResource getInstanceInfo(@PathParam("id") String id) {
return new InstanceResource(this, id, serverConfig, registry);
}
//注册
@POST
@Consumes({"application/json", "application/xml"})
public Response addInstance(InstanceInfo info,
@HeaderParam(PeerEurekaNode.HEADER_REPLICATION) String isReplication) {}
}
刷新状态InstanceResource
@Produces({"application/xml", "application/json"})
public class InstanceResource {
@GET
public Response getInstanceInfo() {}
//更新状态
@PUT
public Response renewLease(
@HeaderParam(PeerEurekaNode.HEADER_REPLICATION) String isReplication,
@QueryParam("overriddenstatus") String overriddenStatus,
@QueryParam("status") String status,
@QueryParam("lastDirtyTimestamp") String lastDirtyTimestamp) {}
@PUT
@Path("status")
public Response statusUpdate(
@QueryParam("value") String newStatus,
@HeaderParam(PeerEurekaNode.HEADER_REPLICATION) String isReplication,
@QueryParam("lastDirtyTimestamp") String lastDirtyTimestamp) {}
@DELETE
@Path("status")
public Response deleteStatusUpdate(
@HeaderParam(PeerEurekaNode.HEADER_REPLICATION) String isReplication,
@QueryParam("value") String newStatusValue,
@QueryParam("lastDirtyTimestamp") String lastDirtyTimestamp) {}
@PUT
@Path("metadata")
public Response updateMetadata(@Context UriInfo uriInfo) {}
@DELETE
public Response cancelLease(
@HeaderParam(PeerEurekaNode.HEADER_REPLICATION) String isReplication) {}
}
先来看注册这个接口
ApplicationResource.addInstance(InstanceInfo info, String isReplication)注册开始
在这个方法里面开始 跟着这个方法走
//添加服务器数据
ApplicationResource.addInstance
//注册像调用
registry.register(info, "true".equals(isReplication)); == InstanceRegistry.register
//向spring容器注册一个服务添加事件 方便你去扩展
handleRegistration(info, resolveInstanceLeaseDuration(info), isReplication);
//添加数据
super.register(info, isReplication);==PeerAwareInstanceRegistryImpl.register
super.register(info, leaseDuration, isReplication);
//从map中拿到这个服务的数据,如果没有得到就创建。
========================
Map<String, Lease<InstanceInfo>> gMap = registry.get(registrant.getAppName());
REGISTER.increment(isReplication);
if (gMap == null) {
final ConcurrentHashMap<String, Lease<InstanceInfo>> gNewMap = new ConcurrentHashMap<String, Lease<InstanceInfo>>();
gMap = registry.putIfAbsent(registrant.getAppName(), gNewMap);
if (gMap == null) {
gMap = gNewMap;
}
}
================================
//把registrant 就是我们要注册的服务数据 添加到map中,
Lease<InstanceInfo> lease = new Lease<InstanceInfo>(registrant, leaseDuration);
if (existingLease != null) {
lease.setServiceUpTimestamp(existingLease.getServiceUpTimestamp());
}
gMap.put(registrant.getId(), lease);
================================
//注册到队列
recentlyChangedQueue.add(new RecentlyChangedItem(lease));
//修改更新时间 用于计算服务有效性
registrant.setLastUpdatedTimestamp();
//清除缓存-如果你这个时候去拉服务 就会有点慢 全部都要
invalidateCache(registrant.getAppName(), registrant.getVIPAddress(), registrant.getSecureVipAddress());
================================
//注册成功向其他服务器节点添加注册
replicateToPeers(Action.Register, info.getAppName(), info.getId(), info, null, isReplication);
这就是注册的接口 就已经完了 ,接下来看 复杂的流程图
总结:当spring启动的时候,创建了bean EurekaBootStrap这个类继承了 ServletContextListener 所里web容器就会去初始化 EurekaBootStrap 初始化流程为
EurekaBootStrap.contextInitialized->
EurekaServerContext.initialize ->
InstanceRegistry.init-> 他的initializedResponseCache()方法 创建了ResponseCacheImpl 对象
ResponseCacheImpl 对象做了 1.在你去拉取服务列表的时候 是这个对象 这对象复制 从注册map中拉数据创建你要的 服务器的列表,并加了一个定时任务,固定时间 的把你注册的数据从注册列表,搬到缓存中来,意思就是说 ,你去服务端拉服务列表的时候,可能是从缓存里面拉也可能是,直接去创建的,