三、eureka服务端获取服务列表
所有文章
https://www.cnblogs.com/lay2017/p/11908715.html
正文
eureka服务端维护了一个服务信息的列表,服务端节点之间相互复制服务信息。而作为eureka的客户端将会从eureka服务端请求这个服务信息列表,选择对应的实例。本文就来看看eureka服务端对客户端提供的获取服务信息列表的http接口。
eureka服务端基于jersey来提供http服务调用,所以我们先找到它的Resource。
ApplicationsResource
- @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) {
- // ...
- Key cacheKey = new Key(Key.EntityType.Application,
- ResponseCacheImpl.ALL_APPS,
- keyType, CurrentRequestVersion.get(), EurekaAccept.fromString(eurekaAccept), regions
- );
- Response response;
- if (acceptEncoding != null && acceptEncoding.contains(HEADER_GZIP_VALUE)) {
- response = Response.ok(responseCache.getGZIP(cacheKey))
- .header(HEADER_CONTENT_ENCODING, HEADER_GZIP_VALUE)
- .header(HEADER_CONTENT_TYPE, returnMediaType)
- .build();
- } else {
- response = Response.ok(responseCache.get(cacheKey))
- .build();
- }
- return response;
- }
这里从responseCache当中获取了Applications的序列号结果直接返回了,所以我们先看看ResponseCache是从哪里来的
可以看到ResponseCache是再ApplicationsResource构造的时候从Registry中获取的
- @Inject
- ApplicationsResource(EurekaServerContext eurekaServer) {
- this.serverConfig = eurekaServer.getServerConfig();
- this.registry = eurekaServer.getRegistry();
- this.responseCache = registry.getResponseCache();
- }
我们再看看ResponseCache的get方法做了什么
- String get(final Key key, boolean useReadOnlyCache) {
- Value payload = getValue(key, useReadOnlyCache);
- if (payload == null || payload.getPayload().equals(EMPTY_PAYLOAD)) {
- return null;
- } else {
- return payload.getPayload();
- }
- }
继续跟进getValue
- Value getValue(final Key key, boolean useReadOnlyCache) {
- Value payload = null;
- try {
- if (useReadOnlyCache) {
- final Value currentPayload = readOnlyCacheMap.get(key);
- if (currentPayload != null) {
- payload = currentPayload;
- } else {
- payload = readWriteCacheMap.get(key);
- readOnlyCacheMap.put(key, payload);
- }
- } else {
- payload = readWriteCacheMap.get(key);
- }
- } catch (Throwable t) {
- logger.error("Cannot get value for key : {}", key, t);
- }
- return payload;
- }
可以看到,其实只是从ReadWriteCacheMap当中获取对应的值,那么我们再看看ReadWriteCacheMap是怎么被构造的
- this.readWriteCacheMap = CacheBuilder.newBuilder().initialCapacity(serverConfig.getInitialCapacityOfResponseCache())
- .expireAfterWrite(serverConfig.getResponseCacheAutoExpirationInSeconds(), TimeUnit.SECONDS)
- .removalListener(new RemovalListener<Key, Value>() {
- @Override
- public void onRemoval(RemovalNotification<Key, Value> notification) {
- Key removedKey = notification.getKey();
- if (removedKey.hasRegions()) {
- Key cloneWithNoRegions = removedKey.cloneWithoutRegions();
- regionSpecificKeys.remove(cloneWithNoRegions, removedKey);
- }
- }
- })
- .build(new CacheLoader<Key, Value>() {
- @Override
- public Value load(Key key) throws Exception {
- if (key.hasRegions()) {
- Key cloneWithNoRegions = key.cloneWithoutRegions();
- regionSpecificKeys.put(cloneWithNoRegions, key);
- }
- Value value = generatePayload(key);
- return value;
- }
- });
从这里可以看出,调用ReadWriteCacheMap的get方法,将会触发这里的generatePayload方法
我们跟进generatePayload
- private Value generatePayload(Key key) {
- Stopwatch tracer = null;
- try {
- String payload;
- switch (key.getEntityType()) {
- case Application:
- boolean isRemoteRegionRequested = key.hasRegions();
- // 获取所有Application
- if (ALL_APPS.equals(key.getName())) {
- if (isRemoteRegionRequested) {
- tracer = serializeAllAppsWithRemoteRegionTimer.start();
- payload = getPayLoad(key, registry.getApplicationsFromMultipleRegions(key.getRegions()));
- } else {
- tracer = serializeAllAppsTimer.start();
- payload = getPayLoad(key, registry.getApplications());
- }
- } else if (ALL_APPS_DELTA.equals(key.getName())) {
- // ...
- } else {
- tracer = serializeOneApptimer.start();
- // 获取某个Application
- payload = getPayLoad(key, registry.getApplication(key.getName()));
- }
- break;
- // ...
- }
- return new Value(payload);
- } finally {
- }
- }
我们看到这里payload主要构成元素是Application,也就是我们需要的服务列表信息。
最后,我们跟进getPayLoad方法,看看这些服务列表信息是怎么被序列号成payload的
- private String getPayLoad(Key key, Applications apps) {
- EncoderWrapper encoderWrapper = serverCodecs.getEncoder(key.getType(), key.getEurekaAccept());
- String result;
- try {
- result = encoderWrapper.encode(apps);
- } catch (Exception e) {
- return "";
- }
- return result;
- }
编码器的实现比较多种,这里就不展开了
总结
获取服务信息列表其实就是从registry当中获取Applications,然后做一次序列化,最后通过http响应回去。总体来说还是比较简单的。
三、eureka服务端获取服务列表的更多相关文章
- springcloud(三):Eureka服务端
一. 因为使用一个注册中心服务器端,n个客户端:n个生产者客户端.n消费者客户端....,所有的客户端最好的方式就是通过对象传递参数,因此需要创建一个公共组件项目,为n个客户端传值提供方便 二.创建公 ...
- SpringCloud02 Eureka知识点、Eureka服务端和客户端的创建、Eureka服务端集群、Eureka客户端向集群的Eureka服务端注册
1 Eureka知识点 按照功能划分: Eureka由Eureka服务端和Eureka客户端组成 按照角色划分: Eureka由Eureka Server.Service Provider.Servi ...
- eureka服务端和客户端的简单搭建
本篇博客简单记录一下,eureka 服务端和 客户端的简单搭建. 目标: 1.完成单机 eureka server 和 eureka client 的搭建. 2.完成eureka server 的添加 ...
- ftpget 从Windows FTP服务端获取文件
/********************************************************************************* * ftpget 从Windows ...
- Spring Cloud官方文档中文版-服务发现:Eureka服务端
官方文档地址为:http://cloud.spring.io/spring-cloud-static/Dalston.SR3/#spring-cloud-eureka-server 文中例子我做了一些 ...
- SpringCloud系列四:Eureka 服务发现框架(定义 Eureka 服务端、Eureka 服务信息、Eureka 发现管理、Eureka 安全配置、Eureka-HA(高可用) 机制、Eureka 服务打包部署)
1.概念:Eureka 服务发现框架 2.具体内容 对于服务发现框架可以简单的理解为服务的注册以及使用操作步骤,例如:在 ZooKeeper 组件,这个组件里面已经明确的描述了一个服务的注册以及发现操 ...
- eureka服务端的高可用
eureka client的高可用这个很简单,只需要向eureka服务端上多注册几个实例即可,那么eureka server端如何实现高可用呢?其实eureka server 端也是可以做为一个客户端 ...
- IE8下服务端获取客户端文件的路径为C:/fakePath问题的解决方案
上一篇文章上提到,IE8下服务端获取客户端文件的路径时,会变成C:/fakePath问题,于是乎通过文件路径去获得文件大小就失败了. 上网搜了一下,主要原因是IE8因为安全考虑,在上传文件时屏蔽了真实 ...
- Android从服务端获取json解析显示在客户端上面
Android从服务端获取json解析显示在客户端上面 百度经验:jingyan.baidu.com 首先说一下Json数据的最基本的特点,Json数据是一系列的键值对的集合,和XML数据来比,Jso ...
随机推荐
- linux内核睡眠状态解析
1. 系统睡眠状态 睡眠状态是整个系统的全局低功耗状态,在这种状态下,用户空间的代码不能被执行并且整个系统的活动明显被降低 1.1 被支持的睡眠状态 取决于所运行平台的能力和配置选项,Linux内核能 ...
- bat命令编写大全
bat命令编写大全 摘自:https://blog.csdn.net/haibo19981/article/details/52161653 2016年08月09日 12:26:31 爱睡觉的猫L 阅 ...
- OpenStack社区中的GO语言之争
1 背景介绍 Swift之前几乎所有的代码都是用Python实现的,但是性能一直不理想, 社区为了解决性能问题,尝试过很多方法,后来发现用Golang语言进行一部分代码重写, 性能得到了一定的提升,社 ...
- 利用Python获取cookie的方法,相比java代码简便不少
1.通过urllib库,是python的标准库,不需要另外引入,直接看代码,注意代码的缩进: # coding=UTF-8import cookielibimport urllib2 class Ry ...
- git命令手册
以下内容是我在学习和研究Git时,对Git操作的特性.重点和注意事项的提取.精练和总结,可以做为Git操作的字典,方便大家查阅: 备注:本文会不断更新完善: 目录 一. 语法格式描述 二. git环境 ...
- laravel构建联合查询
参考:http://laravelacademy.org/post/126.html DB门面可以指定不同的数据库连接(通过connection方法) /** * @param $login_uid ...
- 【Leetcode_easy】744. Find Smallest Letter Greater Than Target
problem 744. Find Smallest Letter Greater Than Target 题意:一堆有序的字母,然后又给了一个target字母,让求字母数组中第一个大于target的 ...
- idea的enable auto-import/内存设置
设置pom.xml依赖的自动导入 设置idea的memory heap On the Help menu, click Edit Custom VM Options. Set the -Xmx opt ...
- WEB前端动态背景集
本资源是我在源代码网站上发现的,内附几十种背景动态特效,我单独提取出来精品背景特效在此分享,文件里有20多种精品动态效果,本人觉得可用作于个人博客主页背景,登陆页面背景等,有20多个背景特效,非常漂亮 ...
- pod install安装第三方库异常
使用pod install安装第三方插件时,可能会出现如下异常: Installing SDWebImage (3.7.3) [!] Error installing SDWebImage[!] /u ...