需要做的:

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

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

  返回DiscoveryClient的顺序

  返回HealthIndicator里显示的描述

实现LoadBalanceClient

  实现自己的ServiceList<T extends Server>

    Ribbon提供了AbstractServerList<T extends Server>

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

pom引入

        <dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency> <dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

bootstartp.properties

spring.application.name=name-service

application.yaml

server:
port: #需要连接的服务
conns:
services:
- localhost:

DiscoveryClient服务列表

import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.client.DefaultServiceInstance;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient; import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors; @ConfigurationProperties(prefix = "conns")
@Setter
@Slf4j
public class MyDiscoveryClient implements DiscoveryClient { public static final String SERVICE_ID = "conn-service";
// waiter.services
private List<String> services; @Override
public String description() {
return "DiscoveryClient that uses service.list from application.yml.";
} @Override
public List<ServiceInstance> getInstances(String serviceId) {
if (!SERVICE_ID.equalsIgnoreCase(serviceId)) {
return Collections.emptyList();
}
// 这里忽略了很多边界条件判断,认为就是 HOST:PORT 形式
return services.stream()
.map(s -> new DefaultServiceInstance(s,
SERVICE_ID,
s.split(":")[],
Integer.parseInt(s.split(":")[]),
false)).collect(Collectors.toList());
} @Override
public List<String> getServices() {
return Collections.singletonList(SERVICE_ID);
}
}
ServerList
import java.util.List;
import java.util.stream.Collectors; public class MyServerList implements ServerList<Server> { @Autowired
private MyDiscoveryClient discoveryClient; @Override
public List<Server> getInitialListOfServers() {
return getServers();
} @Override
public List<Server> getUpdatedListOfServers() {
return getServers();
} private List<Server> getServers() {
return discoveryClient.getInstances(MyDiscoveryClient.SERVICE_ID).stream()
.map(i -> new Server(i.getHost(), i.getPort()))
.collect(Collectors.toList());
}
}

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

注入bean

 @Bean
public DiscoveryClient myDiscovery(){
return new MyDiscoveryClient();
} @Bean
public MyServerList myServerList() {
return new MyServerList();
} @Bean
public HttpComponentsClientHttpRequestFactory requestFactory() {
PoolingHttpClientConnectionManager connectionManager =
new PoolingHttpClientConnectionManager(, TimeUnit.SECONDS);
connectionManager.setMaxTotal();
connectionManager.setDefaultMaxPerRoute(); CloseableHttpClient httpClient = HttpClients.custom()
.setConnectionManager(connectionManager)
.evictIdleConnections(, TimeUnit.SECONDS)
.disableAutomaticRetries()
// 有 Keep-Alive 认里面的值,没有的话永久有效
//.setKeepAliveStrategy(DefaultConnectionKeepAliveStrategy.INSTANCE)
// 换成自定义的
.setKeepAliveStrategy(new CustomConnectionKeepAliveStrategy())
.build(); HttpComponentsClientHttpRequestFactory requestFactory =
new HttpComponentsClientHttpRequestFactory(httpClient); return requestFactory;
} @LoadBalanced
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder
.setConnectTimeout(Duration.ofMillis())
.setReadTimeout(Duration.ofMillis())
.requestFactory(this::requestFactory)
.build();
}
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.http.HttpResponse;
import org.apache.http.conn.ConnectionKeepAliveStrategy;
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext; import java.util.Arrays; public class CustomConnectionKeepAliveStrategy implements ConnectionKeepAliveStrategy {
private final long DEFAULT_SECONDS = ; @Override
public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
return Arrays.asList(response.getHeaders(HTTP.CONN_KEEP_ALIVE))
.stream()
.filter(h -> StringUtils.equalsIgnoreCase(h.getName(), "timeout")
&& StringUtils.isNumeric(h.getValue()))
.findFirst()
.map(h -> NumberUtils.toLong(h.getValue(), DEFAULT_SECONDS))
.orElse(DEFAULT_SECONDS) * ;
}
}

开启localhost:8088服务

测试:

  

import com.example.discovery.model.TechnologyType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate; import java.util.List; @Component
@Slf4j
public class CustomerRunner implements ApplicationRunner { @Autowired
private RestTemplate restTemplate; @Override
public void run(ApplicationArguments args) throws Exception {
showServiceInstances(); } private void showServiceInstances() {
ParameterizedTypeReference<List<TechnologyType>> ptr =
new ParameterizedTypeReference<List<TechnologyType>>() {};
ResponseEntity<List<TechnologyType>> list = restTemplate
.exchange("http://waiter-service/tech/", HttpMethod.GET, null, ptr);
list.getBody().forEach(t -> log.info("technology: {}", t));
}
}

运行结果

  

TechnologyType{techTypeId='', techTypeName='先进医疗/康复设备', techTypeDesc='', techCreateDate=Wed Sep  :: CST }
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. linux下查看某个文件位置的方法

    linux下查看某个文件位置的方法: 例如,不知道apache的配置文件httpd.conf的位置,可以有两种方法来查看: 1.find / -name httpd.conf2.locate http ...

  2. Vue 实现文件的下载

    上次说了,实现文件的上传需要三步,那么实现文件的下载呢? 答:也是三步 第一步:获取文件的 fileId (或者别的什么的,总之应该是代表这个文件的东西),各家后台需要的都不一样 第二步:调用接口 t ...

  3. c# Winform 调用可执行 exe 文件

    c#是一个写windows桌面小工具的好东西,但有个时候,我们需要在 winform 程序中调用其他的 exe 文件,那么该如何实现呢? 如果只是拉起一个 exe 文件,可以参考如下方法实现: str ...

  4. Linux wc -l 统计行数问题

    统计文件行数   通过wc -l 来实现. [root@xguang_02 xguang]# wc -l tt.dat     798 tt.dat    而通过nl\ cat -n 查看时发现为79 ...

  5. php object

    一.访问控制 <?php class Computer{ public $cpu = 880; private $name = 'xiaomi'; public function getname ...

  6. Nginx+lua_Nginx+GraphicsMagick来实现实时缩略图

    1.安装GraphicsMagick cd /usr/local/src wget http://sourceforge.net/projects/graphicsmagick/files/graph ...

  7. 破坏双亲委托机制的一些情况---Tomcat和JDBC,破坏后的安全问题

    采用双亲委托机制的原因 类加载器就是将字节码搬进jvm方法区的组件.我们知道,JVM识别加载进来的类是通过类加载器+类全名完成的,也就是说同一个类由不同类加载器加载进去的话就会被视为不同的类.jdk提 ...

  8. redis下载及安装教程

    https://blog.csdn.net/w546097639/article/details/88547486

  9. python之requests模块中的params和data的区别

    params的时候之间接把参数加到url后面,只在get请求时使用: import requests url='https://api.ireaderm.net/account/charge/info ...

  10. Knative 实战:基于 Knative Serverless 技术实现天气服务

    提到天气预报服务,我们第一反应是很简单的一个服务啊,目前网上有大把的天气预报 API 可以直接使用,有必要去使用 Knative 搞一套吗?杀鸡用牛刀?先不要着急,我们先看一下实际的几个场景需求: 场 ...