需要做的:

  DiscoveryClient能提供那些服务的服务名列表

  返回指定服务对于的ServiceInstance列表

  返回DiscoveryClient的顺序

  返回HealthIndicator里显示的描述

实现LoadBalanceClient

  实现自己的ServiceList<T extends Server>

    Ribbon提供了AbstractServerList<T extends Server>

  提供一个配置类,声明ServerListBean 实例

pom引入

  1. <dependency>
  2. <groupId>org.springframework.cloud</groupId>
  3. <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
  4. </dependency>
  5.  
  6. <dependencyManagement>
  7. <dependencies>
  8. <dependency>
  9. <groupId>org.springframework.cloud</groupId>
  10. <artifactId>spring-cloud-dependencies</artifactId>
  11. <version>${spring-cloud.version}</version>
  12. <type>pom</type>
  13. <scope>import</scope>
  14. </dependency>
  15. </dependencies>
  16. </dependencyManagement>

bootstartp.properties

  1. spring.application.name=name-service

application.yaml

  1. server:
  2. port:
  3.  
  4. #需要连接的服务
  5. conns:
  6. services:
  7. - localhost:

DiscoveryClient服务列表

  1. import lombok.Setter;
  2. import lombok.extern.slf4j.Slf4j;
  3. import org.springframework.boot.context.properties.ConfigurationProperties;
  4. import org.springframework.cloud.client.DefaultServiceInstance;
  5. import org.springframework.cloud.client.ServiceInstance;
  6. import org.springframework.cloud.client.discovery.DiscoveryClient;
  7.  
  8. import java.util.Collections;
  9. import java.util.List;
  10. import java.util.stream.Collectors;
  11.  
  12. @ConfigurationProperties(prefix = "conns")
  13. @Setter
  14. @Slf4j
  15. public class MyDiscoveryClient implements DiscoveryClient {
  16.  
  17. public static final String SERVICE_ID = "conn-service";
  18. // waiter.services
  19. private List<String> services;
  20.  
  21. @Override
  22. public String description() {
  23. return "DiscoveryClient that uses service.list from application.yml.";
  24. }
  25.  
  26. @Override
  27. public List<ServiceInstance> getInstances(String serviceId) {
  28. if (!SERVICE_ID.equalsIgnoreCase(serviceId)) {
  29. return Collections.emptyList();
  30. }
  31. // 这里忽略了很多边界条件判断,认为就是 HOST:PORT 形式
  32. return services.stream()
  33. .map(s -> new DefaultServiceInstance(s,
  34. SERVICE_ID,
  35. s.split(":")[],
  36. Integer.parseInt(s.split(":")[]),
  37. false)).collect(Collectors.toList());
  38. }
  39.  
  40. @Override
  41. public List<String> getServices() {
  42. return Collections.singletonList(SERVICE_ID);
  43. }
  44. }
  1. ServerList
  1. import java.util.List;
  2. import java.util.stream.Collectors;
  3.  
  4. public class MyServerList implements ServerList<Server> {
  5.  
  6. @Autowired
  7. private MyDiscoveryClient discoveryClient;
  8.  
  9. @Override
  10. public List<Server> getInitialListOfServers() {
  11. return getServers();
  12. }
  13.  
  14. @Override
  15. public List<Server> getUpdatedListOfServers() {
  16. return getServers();
  17. }
  18.  
  19. private List<Server> getServers() {
  20. return discoveryClient.getInstances(MyDiscoveryClient.SERVICE_ID).stream()
  21. .map(i -> new Server(i.getHost(), i.getPort()))
  22. .collect(Collectors.toList());
  23. }
  24. }

开启:@EnableDiscoveryClient  //注册中心注册服务

注入bean

  1. @Bean
  2. public DiscoveryClient myDiscovery(){
  3. return new MyDiscoveryClient();
  4. }
  5.  
  6. @Bean
  7. public MyServerList myServerList() {
  8. return new MyServerList();
  9. }
  10.  
  11. @Bean
  12. public HttpComponentsClientHttpRequestFactory requestFactory() {
  13. PoolingHttpClientConnectionManager connectionManager =
  14. new PoolingHttpClientConnectionManager(, TimeUnit.SECONDS);
  15. connectionManager.setMaxTotal();
  16. connectionManager.setDefaultMaxPerRoute();
  17.  
  18. CloseableHttpClient httpClient = HttpClients.custom()
  19. .setConnectionManager(connectionManager)
  20. .evictIdleConnections(, TimeUnit.SECONDS)
  21. .disableAutomaticRetries()
  22. // 有 Keep-Alive 认里面的值,没有的话永久有效
  23. //.setKeepAliveStrategy(DefaultConnectionKeepAliveStrategy.INSTANCE)
  24. // 换成自定义的
  25. .setKeepAliveStrategy(new CustomConnectionKeepAliveStrategy())
  26. .build();
  27.  
  28. HttpComponentsClientHttpRequestFactory requestFactory =
  29. new HttpComponentsClientHttpRequestFactory(httpClient);
  30.  
  31. return requestFactory;
  32. }
  33.  
  34. @LoadBalanced
  35. @Bean
  36. public RestTemplate restTemplate(RestTemplateBuilder builder) {
  37. return builder
  38. .setConnectTimeout(Duration.ofMillis())
  39. .setReadTimeout(Duration.ofMillis())
  40. .requestFactory(this::requestFactory)
  41. .build();
  42. }
  1. import org.apache.commons.lang3.StringUtils;
  2. import org.apache.commons.lang3.math.NumberUtils;
  3. import org.apache.http.HttpResponse;
  4. import org.apache.http.conn.ConnectionKeepAliveStrategy;
  5. import org.apache.http.protocol.HTTP;
  6. import org.apache.http.protocol.HttpContext;
  7.  
  8. import java.util.Arrays;
  9.  
  10. public class CustomConnectionKeepAliveStrategy implements ConnectionKeepAliveStrategy {
  11. private final long DEFAULT_SECONDS = ;
  12.  
  13. @Override
  14. public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
  15. return Arrays.asList(response.getHeaders(HTTP.CONN_KEEP_ALIVE))
  16. .stream()
  17. .filter(h -> StringUtils.equalsIgnoreCase(h.getName(), "timeout")
  18. && StringUtils.isNumeric(h.getValue()))
  19. .findFirst()
  20. .map(h -> NumberUtils.toLong(h.getValue(), DEFAULT_SECONDS))
  21. .orElse(DEFAULT_SECONDS) * ;
  22. }
  23. }

开启localhost:8088服务

测试:

  

  1. import com.example.discovery.model.TechnologyType;
  2. import lombok.extern.slf4j.Slf4j;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.boot.ApplicationArguments;
  5. import org.springframework.boot.ApplicationRunner;
  6. import org.springframework.core.ParameterizedTypeReference;
  7. import org.springframework.http.HttpMethod;
  8. import org.springframework.http.ResponseEntity;
  9. import org.springframework.stereotype.Component;
  10. import org.springframework.web.client.RestTemplate;
  11.  
  12. import java.util.List;
  13.  
  14. @Component
  15. @Slf4j
  16. public class CustomerRunner implements ApplicationRunner {
  17.  
  18. @Autowired
  19. private RestTemplate restTemplate;
  20.  
  21. @Override
  22. public void run(ApplicationArguments args) throws Exception {
  23. showServiceInstances();
  24.  
  25. }
  26.  
  27. private void showServiceInstances() {
  28. ParameterizedTypeReference<List<TechnologyType>> ptr =
  29. new ParameterizedTypeReference<List<TechnologyType>>() {};
  30. ResponseEntity<List<TechnologyType>> list = restTemplate
  31. .exchange("http://waiter-service/tech/", HttpMethod.GET, null, ptr);
  32. list.getBody().forEach(t -> log.info("technology: {}", t));
  33. }
  34. }

运行结果

  

  1. TechnologyType{techTypeId='', techTypeName='先进医疗/康复设备', techTypeDesc='', techCreateDate=Wed Sep :: CST }
  2. TechnologyType{techTypeId='', techTypeName='大数据', techTypeDesc='null', techCreateDate=Thu Aug :: CST }

实现自己的DiscoveryClient的更多相关文章

  1. SpringCloud学习之DiscoveryClient探究

    当我们使用@DiscoveryClient注解的时候,会不会有如下疑问:它为什么会进行注册服务的操作,它不是应该用作服务发现的吗?下面我们就来深入的来探究一下其源码. 一.Springframewor ...

  2. springcloud-3:required a bean of type 'com.netflix.discovery.DiscoveryClient' that could not be found.

    在写客户端程序的时候,总是报'com.netflix.discovery.DiscoveryClient' that could not be found. 原因在于导入了错误的类:com.netfl ...

  3. SpringCloud报错: "Field discoveryClient in com.controller.DcController required a bean of type 'com.netflix.discovery.DiscoveryClient' that could not be found."

    SpringCloud报错: "Field discoveryClient in com.controller.DcController required a bean of type 'c ...

  4. spring eureka required a bean of type 'com.netflix.discovery.DiscoveryClient' that could not be found.

    spring在集成第三方过程很容易出现类名相同,且基本作用相同的类.这样给初学者带来一定的困惑. 导致用错类而出现以下问题. required a bean of type 'com.netflix. ...

  5. Spring Cloud之DiscoveryClient使用

    主要修改zk order的代码: package com.toov5.api.controller; import java.util.List; import org.springframework ...

  6. 深入理解DiscoveryClient

    Spring Cloud Commons 提供的抽象 最早的时候服务发现注册都是通过DiscoveryClient来实现的,随着版本变迁把DiscoveryClient服务注册抽离出来变成了Servi ...

  7. com.netflix.discovery.DiscoveryClient : Completed shut down of DiscoveryClient

    启动报错:com.netflix.discovery.DiscoveryClient    : Completed shut down of DiscoveryClient 解决方案: 添加web主件 ...

  8. client-go实战之五:DiscoveryClient

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  9. SpringCloud发现服务代码(EurekaClient,DiscoveryClient)

    1.说明 本文介绍SpringCloud发现服务代码的开发, 通过使用EurekaClient,DiscoveryClient来发现注册中心的服务等, 从而可以自定义客户端对注册中心的高级用法. 2. ...

随机推荐

  1. js中基本数据类型与引用数据类型的本质区别

    代码 /** * 基本数据类型:string, number, boolean, null, undefined. * * 说明: * 基本数据类型的变量是保存在栈内存中的,基本数据类型的值 * 直接 ...

  2. 基本SQL查询语句

    使用Emp表和Dept表完成下列练习 Emp员工表 empno ename job Mgr Hiredate Sal Comm Deptno 员工号 员工姓名 工作 上级编号 受雇日期 薪金 佣金 部 ...

  3. ReactiveCocoa详解

    最近看了大神的博客后,感觉该对ReactiveCocoa做一个了断了. 首先大致的对以下关于ReactiveCocoa内容做一个简单的总结,其他的后续更新 1.ReactiveCocoa的操作思想 2 ...

  4. vue修改Element的el-table样式

    修改Element中的el-table样式,可以使用以下几种方法: 1. row-style 行的 style 的回调方法,也可以使用一个固定的 Object 为所有行设置一样的 Style. 2. ...

  5. 【技巧】Windows 10 1809无法接收1903解决方法

    这都7月份了,Windows10 1903都升级的有一个月了,然而我的1809的系统一直找不到1903的更新. 虽说1903会有bug,但还是想体验一把.周围同事都更新了,心里还是痒痒的. 于是每天都 ...

  6. 【Kickstart】2018 Round (Practice ~ C)

    Practice Round Problem A GBus count (9pt/15pt) (2019年1月14日,kickstart群每日一题) 题意:有一条笔直的大路,上面有城市编号从 1 开始 ...

  7. error: must use ‘class’ tag to refer to type ‘XXX’ in this scope

    开发环境: Qt Creator 4.8.2 在写程序的时候,遇到了编译器报错 error: must use 'class' tag to refer to type 'XXX' in this s ...

  8. bzoj3123 [Sdoi2013]森林 树上主席树+启发式合并

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=3123 题解 如果是静态的查询操作,那么就是直接树上主席树的板子. 但是我们现在有了一个连接两棵 ...

  9. 多组件共享-vuex

    1.解决多个组件共享同一状态数据问题1)多个视图共享同一状态2)来自不同视图的触发事件需要变更同一状态文档API:https://vuex.vuejs.org/zh/api/ 2.组件与store连接 ...

  10. loadrunner 使用

    loadrunner给我的感觉很强势吧,第一次接触被安装包吓到了,当时用的是win10安装11版本的,各种安装失败,印象很深刻,那时候全班二三十号人,搞环境搞了两天,后来无奈,重做系统换成win7的了 ...