Myclustereurekainaction基于本地服务消费
1 概述
SpringCloud基于Greenwich.RELEASE版本。
本文着重学习通过配置 ribbon.eureka.enable 为false 来禁止调用Eureka Client 获取注册列表,从配置的指定服务示例列表中获取服务。章节2.3是本文讨论的重点。
1.1工程结构
image.png图 1 工程结构
1.2主maven依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.kikop.myeurekainaction</groupId>
<artifactId>mysingleeurekainaction</artifactId>
<version>1.0-SNAPSHOT</version>
<modules>
<module>eureka-server</module>
<module>eureka-client</module>
</modules>
<packaging>pom</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
</properties>
<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>
</project>
2 eureka Server高可用集群模式
2.1 clustereurekaserver注册中心
作为eureka的注册中心。需引用spring-cloud-starter-netflix-eureka-server。
端口分别为:8761、8762
2.1.1 maven依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>myclustereurekainaction</artifactId>
<groupId>com.kikop.myclustereurekainaction</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>eureka-server-cluster</artifactId>
<dependencies>
<!--1.eureka server服务注册中心-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<!--4.test-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--5.actuator-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.1.2 resources(application.yml)配置
2.1.2.1 引导配置
spring:
profiles:
active: peer1
2.1.2.2 节点1(application-peer1.yml)
#定义了两个profile 文件,分别为peerl 和peer2 ,它们的hostname 分别为peerl
#和peer2 。在实际开发中,可能是具体的服务器F 地址,它们的端口分别为8761 和8762
#因为是在本地搭建Eureka Server 集群,所以需要修改本地的host文件,windows系统的电脑
#在C:\Windows\System32\drivers\etc\hosts 中修改
# 127.0.0.1 peer1
# 127.0.0.1 peer2
---
spring:
profiles: peer1
application:
name: eurekaservercluster
server:
port: 8761
eureka:
instance:
hostname: peer1
client:
service-url:
defaultZone: http://peer2:8762/eureka/ # 注意: peer1要连接peer2的eureka地址
server:
peer-node-read-timeout-ms: 2000
2.1.2.3 节点2
#定义了两个profile 文件,分别为peerl 和peer2 ,它们的hostname 分别为peerl
#和peer2 。在实际开发中,可能是具体的服务器F 地址,它们的端口分别为8761 和8762
#因为是在本地搭建Eureka Server 集群,所以需要修改本地的host文件,windows系统的电脑
#在C:\Windows\System32\drivers\etc\hosts 中修改
# 127.0.0.1 peer1
# 127.0.0.1 peer2
spring:
profiles: peer2
application:
name: eurekaservercluster
server:
port: 8762
eureka:
instance:
hostname: peer2
client:
service-url:
defaultZone: http://peer1:8761/eureka/ # 注意: peer2要连接peer1的eureka地址
server:
peer-node-read-timeout-ms: 2000
2.1.2.4 hosts配置
127.0.0.1 peer1
127.0.0.1 peer2
2.1.3 JavaMain入口
package com.kikop.eurekaservercluster;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
// 开启 eureka 服务注册
@EnableEurekaServer
//开启组件扫描、bean nest 配置、自动配置
@SpringBootApplication
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
2.1.4测试
查看服务中心
[图片上传失败...(image-c556ba-1595164737029)]
图 2 单个8761节点启动
[图片上传失败...(image-2001e0-1595164737028)]
图 3 8761节点情况
[图片上传失败...(image-e3f892-1595164737028)]
图 4 8762节点情况
2.2 eurekaprovider服务提供者
作为eureka的client_P端,需引用:
spring-cloud-starter-netflix-eureka-client。
2.2.1 maven依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>myclustereurekainaction</artifactId>
<groupId>com.kikop.myclustereurekainaction</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>eureka-provider-cluster</artifactId>
<dependencies>
<!--1.eureak服务提供者-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--3.web服务-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--4.test-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--5.actuator-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.1.2.1 引导配置
spring:
profiles:
# 指向 application-node1.xml
active: node1
eureka:
client:
# 高可用的服务注册中心 eureka-server-cluster,端口号分布为:8761,8762
service-url:
defaultZone: http://peer1:8761/eureka/
2.1.2.2 节点1(application-peer1.yml)
spring:
application:
# 服务提供者名称一样
name: eureka-provider
server:
port: 8861
2.1.2.3 节点2
spring:
application:
# 服务提供者名称一样
name: eureka-provider
server:
port: 8862
2.2.3 Java
2.2.3.1 main入口
package com.kikop.eurekaprovidercluster;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
// 开启 EnableEurekaClient 注解,注册到EurekaServer服务端
@EnableEurekaClient
// springboot应用程序
@SpringBootApplication
public class EurekaProviderApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaProviderApplication.class, args);
}
}
2.2.3.2 controller
package com.kikop.eurekaprovidercluster.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* @author kikop
* @version 1.0
* @project Name: myeurekainaction
* @file Name: ProviderController
* @desc 功能描述
* @date 2020/2/9
* @time 11:02
* @by IDE: IntelliJ IDEA
*/
@RestController
public class ProviderController {
@Value("${server.port}")
String port;
@GetMapping("/sayHi")
public String sayHi(@RequestParam String name) {
return "sayHi, "+name+",i am from port:" +port;
}
}
2.2.4测试
基本接口测试:
http://localhost:8861/provider/sayHi?name=kikop,即使脱离eurekaserver,仍能正常启动。
如果是服务消费者,需要走eurekaserver,将无法启动。
[图片上传失败...(image-f16c07-1595164737026)]
[图片上传失败...(image-704ea9-1595164737026)]
[图片上传失败...(image-3dd9e9-1595164737026)]
[图片上传失败...(image-b8c0d0-1595164737026)]
2.3 eurekaconsumer_restTemplate(byLocalServerList)服务消费者
Api用到,需引用:
spring-cloud-starter-netflix-eureka-client。
2.3.1 maven依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>myclustereurekainaction</artifactId>
<groupId>com.kikop.myclustereurekainaction</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>eureka-consumer-localserverlist</artifactId>
<dependencies>
<!--1.eureak服务提供者-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--2.netflix-ribbon(本地缓存不需要)-->
<!--<dependency>-->
<!--<groupId>org.springframework.cloud</groupId>-->
<!--<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>-->
<!--</dependency>-->
<!--3.web服务-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--4.test-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--5.actuator-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
</project>
2.3.2 resources(application.yml)配置
# 有两个不同Uri 地址(例如example.com 和google.com )的服务实例,通过stores.ribbon.listOfServers 来配置这些服务实例的Uri
stores:
ribbon:
listOfServers: http://localhost:8861,http://localhost:8862
# 关闭 通过eureka获取服务注册列表功能
ribbon:
eureka:
enabled: false
# 关闭eureka的自我注册功能
eureka:
client:
registerWithEureka: false
fetchRegistry: false
spring:
application:
name: eureka-consumer-localserverlist
server:
port: 8961
2.3.3 Java
2.3.3.1 main
package com.kikop.eureakconsumer.localserverlst;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author kikop
* @version 1.0
* @project Name: myribbon
* @file Name: EurekaRibbonClientApplication
* @desc 功能描述 负载均衡(restTemplate&ribbon)
* @date 2020/2/8
* @time 13:51
* @by IDE: IntelliJ IDEA
*/
// 取消作为eureka-client,缓存列表本地维护
// 通过配置 ribbon.eureka.enable 为false 来禁止调用Eureka Client 获取注册列表,从配置的指定服务示例列表中获取服务。
// @EnableEurekaClient
@SpringBootApplication
public class EurekaConsumerLocalServerLstApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaConsumerLocalServerLstApplication.class, args);
}
}
2.3.3.2 util
package com.kikop.eureakconsumer.localserverlst.util;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.client.RestTemplate;
import java.nio.charset.Charset;
import java.util.List;
/**
* @author kikop
* @version 1.0
* @project Name: myribboninaction
* @file Name: RestTemplateUtil
* @desc 功能描述 解决RestTemplate请求中文乱码
* @date 2020/2/9
* @time 14:46
* @by IDE: IntelliJ IDEA
* @sample https://blog.csdn.net/mryang125/article/details/80963280
*/
public class RestTemplateRespUtf8Util {
/**
* 获取restTemplate实例
*
* @param charset utf-8
* @return
*/
public static RestTemplate getInstance(String charset) {
// 如果是 StringHttpMessageConverter,则修改器默认字符集:ISO-8859-1为utf-8
// postForObject 底层均采用了 MappingJackson2HttpMessageConverter来处理请求
// String格式提交数据时,底层其实采用的是 StringHttpMessageConverter来处理请求
RestTemplate restTemplate = new RestTemplate();
List<HttpMessageConverter<?>> list = restTemplate.getMessageConverters();
for (HttpMessageConverter<?> httpMessageConverter : list) {
if (httpMessageConverter instanceof StringHttpMessageConverter) {
((StringHttpMessageConverter) httpMessageConverter).setDefaultCharset(Charset.forName(charset));
break;
}
}
return restTemplate;
}
}
2.3.3.3 service
2.3.3.4 controller
package com.kikop.eureakconsumer.localserverlst.controller;
import com.kikop.eureakconsumer.localserverlst.util.RestTemplateRespUtf8Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
/**
* @author kikop
* @version 1.0
* @project Name: myribboninaction
* @file Name: RibbonController
* @desc 功能描述
* @date 2020/2/9
* @time 11:02
* @by IDE: IntelliJ IDEA
*/
@RestController
@RequestMapping("/consumer")
public class LocalServiceLoopController {
@Autowired
private LoadBalancerClient loadBalancer;
/**
* 本地服务负载均衡
* @return
*/
@GetMapping("/queryByLocalServListForLB")
public String queryByLocalServListForLB() {
ServiceInstance instance = loadBalancer.choose("stores");
String currentServ = String.format("http://%s:%d", instance.getHost(), instance.getPort());
System.out.println(currentServ);
// RestTemplate restTemplate = new RestTemplate();
RestTemplate restTemplate = RestTemplateRespUtf8Util.getInstance("utf-8");
return restTemplate.getForObject(currentServ+"/provider/sayHi?name={1}", String.class, "海阔天空");
}
}
2.4测试
[图片上传失败...(image-7d7d4e-1595164737024)]
[图片上传失败...(image-97a3a4-1595164737024)]
参考
- Springcloud
网友评论