现在服务提供方已经可以通过Eureka进行注册了,但对于服务的消费者,目前并没有处理,对于服务的消费方,也应该连接上eureka,进行服务的获取,这个时候就应该使用Ribbon这个组件了。
ribbon对应的pom文件如下
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
注意:如果是Edgware或之前的版本,ribbon文件如下
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency
在用到负载均衡之前,先要到eureka中获取相关的服务,所以我们这一块依然需要用到eureka,但eureka中已经内置集成了ribbon,所以在pom文件中,并不需要显示引入ribbon的依赖
Ribbon的基本使用
【springcloud-consumer】 修改pom文件,增加eureka的支持
<?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>springcloud</artifactId>
<groupId>enjoy</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>springcloud-consumer</artifactId>
<dependencies>
<dependency>
<groupId>enjoy</groupId>
<artifactId>springcloud-api</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-devtools</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
</project>
【springcloud-consumer】 修改RestConfig配置类,在获取RestTemplate对象的时候加入Ribbon的配置信息
package cn.enjoy.config;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.web.client.RestTemplate;
import java.nio.charset.Charset;
import java.util.Base64;
@Configuration
public class RestConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
@Bean
public HttpHeaders getHeaders() { // 要进行一个Http头信息配置
HttpHeaders headers = new HttpHeaders(); // 定义一个HTTP的头信息
String auth = "root:enjoy"; // 认证的原始信息
byte[] encodedAuth = Base64.getEncoder()
.encode(auth.getBytes(Charset.forName("US-ASCII"))); // 进行一个加密的处理
String authHeader = "Basic " + new String(encodedAuth);
headers.set("Authorization", authHeader);
return headers;
}
}
【springcloud-consumer】修改application.yml文件,增加Eureka服务注册相关信息
server:
port: 80
eureka:
client:
register-with-eureka: false
service-url:
defaultZone: http://admin:enjoy@eureka1:7001/eureka,http://admin:enjoy@eureka2:7002/eureka,http://admin:enjoy@eureka3:7003/eureka
【springcloud-consumer】修改项目启动类,增加Eureka客户端的配置注解
package cn.enjoy;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
public class ConsumerApp {
public static void main(String[] args) {
SpringApplication.run(ConsumerApp.class,args);
}
}
【springcloud-consumer】 修改ConsumerProductController控制器
现在在eureka中注册的服务名称都是大写字母:
SPRINGCLOUD-PROVIDER-PRODUCT
package cn.enjoy.controller;
import cn.enjoy.vo.Product;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import java.util.List;
@RestController
@RequestMapping("/consumer")
public class ConsumerProductController {
public static final String PRODUCT_GET_URL = "http://MICROCLOUD-PROVIDER-PRODUCT/prodcut/get/";
public static final String PRODUCT_LIST_URL="http://MICROCLOUD-PROVIDER-PRODUCT/prodcut/list/";
public static final String PRODUCT_ADD_URL = "http://MICROCLOUD-PROVIDER-PRODUCT/prodcut/add/";
@Resource
private RestTemplate restTemplate;
@Resource
private HttpHeaders httpHeaders;
@RequestMapping("/product/get")
public Object getProduct(long id) {
Product product = restTemplate.exchange(PRODUCT_GET_URL + id,HttpMethod.GET,new HttpEntity<Object>(httpHeaders), Product.class).getBody();
return product;
}
@RequestMapping("/product/list")
public Object listProduct() {
List<Product> list = restTemplate.exchange(PRODUCT_LIST_URL,HttpMethod.GET,new HttpEntity<Object>(httpHeaders), List.class).getBody();
return list;
}
@RequestMapping("/product/add")
public Object addPorduct(Product product) {
Boolean result = restTemplate.exchange(PRODUCT_ADD_URL, HttpMethod.POST,new HttpEntity<Object>(product,httpHeaders), Boolean.class).getBody();
return result;
}
}
访问地址:http://localhost/consumer/product/list
这个时候Ribbon与Eureka已经整合成功
Ribbon负载均衡的实现
通过上面的代码发现我们用到了一个注解@LoadBalanced,根据这名字大概就能知道Ribbon是可以实现负载均衡的。
【springcloud-provider-product】 复制两份
分别为【springcloud-provider-product2】与【springcloud-provider-product3】
【springcloud数据库】复制两份
分别为【springcloud2数据库】【springcloud3数据库】 里面分别执行spingcloud数据库的脚本
【springcloud-provider-product2】修改application.yml文件如下
server:
port: 8081
mybatis:
mapper-locations: # 所有的mapper映射文件
- classpath:mapping/*.xml
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource # 配置当前要使用的数据源的操作类型
driver-class-name: com.mysql.cj.jdbc.Driver # 配置MySQL的驱动程序类
url: jdbc:mysql://localhost:3306/springcloud2?serverTimezone=GMT%2B8 # 数据库连接地址
username: root # 数据库用户名
password: root1234% # 数据库连接密码
application:
name: springcloud-provider-product
# security:
# user:
# roles:
# - USER # 授权角色
# name: root
# password: enjoy
logging:
level:
cn.enjoy.mapper: debug
eureka:
client: # 客户端进行Eureka注册的配置
service-url:
#defaultZone: http://admin:enjoy@localhost:7001/eureka
defaultZone: http://admin:enjoy@eureka1:7001/eureka,http://admin:enjoy@eureka2:7002/eureka,http://admin:enjoy@eureka3:7003/eureka
instance:
instance-id: springcloud-provider-product2
prefer-ip-address: true
lease-renewal-interval-in-seconds: 2 # 设置心跳的时间间隔(默认是30秒)
lease-expiration-duration-in-seconds: 5 # 如果现在超过了5秒的间隔(默认是90秒)
info:
app.name: springcloud-provider-product2
company.name: enjoy
build.artifactId: $project.artifactId$
build.modelVersion: $project.modelVersion$
【springcloud-provider-product3】修改application.yml文件如下
server:
port: 8082
mybatis:
mapper-locations: # 所有的mapper映射文件
- classpath:mapping/*.xml
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource # 配置当前要使用的数据源的操作类型
driver-class-name: com.mysql.cj.jdbc.Driver # 配置MySQL的驱动程序类
url: jdbc:mysql://localhost:3306/springcloud3?serverTimezone=GMT%2B8 # 数据库连接地址
username: root # 数据库用户名
password: root1234% # 数据库连接密码
application:
name: springcloud-provider-product
# security:
# user:
# roles:
# - USER # 授权角色
# name: root
# password: enjoy
logging:
level:
cn.enjoy.mapper: debug
eureka:
client: # 客户端进行Eureka注册的配置
service-url:
#defaultZone: http://admin:enjoy@localhost:7001/eureka
defaultZone: http://admin:enjoy@eureka1:7001/eureka,http://admin:enjoy@eureka2:7002/eureka,http://admin:enjoy@eureka3:7003/eureka
instance:
instance-id: springcloud-provider-product3
prefer-ip-address: true
lease-renewal-interval-in-seconds: 2 # 设置心跳的时间间隔(默认是30秒)
lease-expiration-duration-in-seconds: 5 # 如果现在超过了5秒的间隔(默认是90秒)
info:
app.name: springcloud-provider-product3
company.name: enjoy
build.artifactId: $project.artifactId$
build.modelVersion: $project.modelVersion$
分别启动3个服务提供方,访问
http://localhost:8080/prodcut/get/1
http://localhost:8081/prodcut/get/1
http://localhost:8082/prodcut/get/1
确认3个服务是能正确提供访问的
【springcloud-consumer】启动
访问:http://localhost/consumer/product/list
现在发现每一次获取数据都是通过不同的微服务获得的,所以现在同一个消费端就可以通过 Ribbon 实现了负载均衡配置处理。