本次项目在父工程上搭建三个工程
父工程pom
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.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>
eureka-server搭建–8761
这是eureka服务端
pom文件
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
application.yml
server:
port: 8761
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
启动类加注解@EnableEurekaServer声明是一个eureka服务器
eureka-client搭建–8762 or 8763
这是服务提供者
pom文件
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
yml文件
server:
port: 8763
spring:
application:
name: eureka-client
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
启动类加@EnableEurekaClient
controller代码如下
@RestController
public class HiController {
@Value("${server.port}")
String port;
@GetMapping("/hi")
public String home(@RequestParam String name) {
return "hi "+name+",i am from port:" +port;
}
}
这个工程可以启动两个实例,通过修改idea的如下配置
第二个实例修改端口号为8762
eureka-ribbon-client搭建–8764
pom文件
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
yml文件
spring:
application:
name: eureka-ribbon-client
server:
port: 8764
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
配置类
@Configuration
public class RibbonConfig {
/**
* 在此类中为IoC 容器中注入一个RestTemplate 的Bean , 并在这个Bean 上加上@LoadBalanced 注解,此时RestTemplate 就结合了
* Ribbon 开启了负载均衡功能。
* @return
*/
@Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
}
service
@Service
public class RibbonService {
@Autowired
RestTemplate restTemplate;
/**
* 在该类的hi()方法用restTemplate调用eureka-client的API接口 Uri 上不需要使用硬编码(比如IP),只需要写服务名eureka-client即可
* 程序会根据服务名称 eureka-client到Eureka-server注册中心去自动获取IP和端口信息。
* @param name
* @return
*/
public String hi(String name) {
return restTemplate.getForObject("http://eureka-client/hi?name="+name,String.class);
}
}
controller
@RestController
public class RibbonController {
/**
* 写一个"/hi" Get 方法的接口,调用RibbonService 类的hi()方法
*/
@Autowired
RibbonService ribbonService;
@GetMapping("/hi")
public String hi(@RequestParam(required = false,defaultValue = "forezp") String name){
return ribbonService.hi(name);
}
@Autowired
private LoadBalancerClient loadBalancer;
/**
* 通过LoadBalancerClient 去选择一个eureka-client 的服务实例的信息, 并将该信息返回
*
*/
@GetMapping("/testRibbon")
public String testRibbon() {
ServiceInstance instance = loadBalancer.choose("eureka-client");
return instance.getHost()+":"+instance.getPort();
}
}
测试
访问http://localhost:8764/hi
交替显示hi forezp,i am from port:8763和hi forezp,i am from port:8762
LoadBalancerClient 简介与演示
1.介绍: 负载均衡器的核心类为LoadBalancerClient, LoadBalancerCiient 可以获取负载均衡的服务提供者的实例信息。
2.在RibbonController类中写一个接口"/testRibbon", 通过LoadBalancerClient 去选择一个eureka-client 的服务实例的信息, 并将该信息返回。
3.在浏览器上多次访问访问http://localhost:8764/testRibbon , 浏览器会轮流显示如下内容:
localhost:8762
localhost:8763
4.本示例只演示负载均衡器LoadBalancerClient 是从Eureka Client 获取服务注册列表信息的,并将服务注册列表信息缓存了一份。
在LoadBalancerClient 调用choose()方法时,根据负载均衡策略选择一个服务实例的信息,从而进行了负载均衡。
注意: eureka client从eureka server获取注册列表信息,LoadBalancerClient从本地的eureka client获取注册列表。
LoadBalancerClient不从eureka获取服务,自己维护一份服务注册列表信息演示
Ribbon Client工程
通过配置ribbon.eureka.enable 为false来禁止调用Eureka Client 获取注册列表,从配置的指定服务示例列表中获取服务。
一: 编写Ribbon Client:
1.在POM文件中引入依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
- 配置application.yml
#服务名为stores有两个不同Uri 地址(例如example.com 和google.com )的服务实例,通过stores.ribbon.listOfServers 来配置这些服务实例的Uri
stores:
ribbon:
listOfServers: example.com,google.com
# 设置通过eureka获取服务注册列表功能 关闭
ribbon:
eureka:
enabled: false
# 关闭eureka的自我注册功能
eureka:
client:
registerWithEureka: false
fetchRegistry: false
server:
port: 8769
- 新建一个RestController类,创建一个API 接口“/testRibbon ”。在RestController 类注入 LoadBalancerClient,通过LoadBalancerClient 的choose(“stores”)方法获取服务实例的信息。
@RestController
public class RibbonController {
@Autowired
private LoadBalancerClient loadBalancer;
@GetMapping("/testRibbon")
public String testRibbon() {
ServiceInstance instance = loadBalancer.choose("stores");
return instance.getHost()+":"+instance.getPort();
}
}
- 启动服务后,在浏览器上访问http://localhost:8769/testRibbon, 浏览器显示如下信息:
example.com:80
google.com:80
现在我们可以知道,在Ribbon 中的负载均衡客户端为LoadBalancerClient 。在Spring Cloud项目中,负载均衡器Ribbon 会默认从Eureka Client 的服务注册列表中获取服务的信息,并缓存一份。根据缓存的服务注册列表信息,可以通过LoadBalancerClient 来选择不同的服务实例, 从而实现负载均衡。如果禁止Ribbon 从Eureka 获取注册列表信息,则需要自己去维护一份服 务注册列表信息。根据自己维护服务注册列表的信息, Ribbon 也可以实现负载均衡。