SpringCloud客戶端負載均衡Ribbon
上一篇寫到關於SpringCloudEureka的相關知識:SpringCloud學習之Eureka。我們實現的服註冊中心,以及服務提供者。接下來記錄關於服務消費,以及客戶端負載均衡器Ribbon的簡單使用和配置。在使用Ribbon之前,先看看怎麼呼叫服務吧。
基礎的服務消費
服務提供者
在上一篇的基礎之上,建立一個service-user
的微服務。這個微服我使用了h2資料庫來儲存資料,所以需要在配置檔案中新增關於資料庫的配置以及在pom檔案中新增依賴,
application.yml
server:
port: 40000
spring:
application:
name: user-service
#===========================================================
# 資料庫配置
#===========================================================
jpa:
show-sql: true
hibernate:
ddl-auto: none
generate-ddl: false
datasource:
platform: h2
schema: classpath:schema.sql
data: classpath:data.sql
#===========================================================
# eureka配置
#===========================================================
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8888/eureka/
instance:
prefer-ip-address: true
instance-id: ${spring.application.name}:${server.port}
pom.xml
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency> </dependencies>
然後編寫資料庫檔案初始化資料;
schema.sql
DROP TABLE user if EXISTS ;
create table user (
id int generated by DEFAULT as IDENTITY,
username VARCHAR (40),
age INT(3),
PRIMARY KEY (id)
);
data.sql
insert into user (id,username,age) values (1,'張三',20);
insert into user (id,username,age) values (2,'李四',25);
insert into user (id,username,age) values (3,'王五',23);
insert into user (id,username,age) values (4,'趙六',30);
User實體類,這裡使用了lombok
工具
@Entity
@Data
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column
private String username;
@Column
private int age;
}
然後建立UserRepository
和UserController
,在UserController
中新增一個根據id查詢的介面:
@Autowired
private UserRepository userRepository;
@GetMapping("/user/{id}")
public User findById(@PathVariable("id") Long id){
return userRepository.findOne(id);
}
在SpringBoot
入口類上新增@EnableEurekaClient
註解
@EnableEurekaClient
@SpringBootApplication
public class UserApplication {
public static void main(String[] args) {
SpringApplication.run(UserApplication.class, args);
}
}
最終的專案結構:
啟動專案,訪問:http://localhost:40000/user/1
服務消費
這裡直接修改上一篇service-article
服務,用service-article
服務來呼叫service-user
服務。所以需要修改service-article
,新增User
物件和ArticleController
,在ArticleController
中新增一個查詢介面。
這裡呼叫服務都是使用RestTemplate
,所以先在入口內中註冊註冊RestTemplate
,
@SpringBootApplication
@EnableEurekaClient
public class ArticleApplication {
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(ArticleApplication.class, args);
}
}
User實體,可以直接拷貝user微服務的實體類去掉註解即可,因為這裡不是持久化物件。
@Data
public class User implements Serializable {
private Long id;
private String username;
private int age;
}
ArticleController
@RestController
public class ArticleController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/a/u/{id}")
public User getUser(@PathVariable("id") Long id){
return restTemplate.getForObject("http://localhost:40000/user/{1}",User.class,id);
}
}
使用Ribbon
介紹
SpringCloudRibbon是一個基於HTTP和TCP的客戶端負載均衡工具。是基於Netfix Ribbon實現的。SpringCloud將其封裝,可以讓我們輕鬆的將面向服務的REST模板自動轉換成客戶端負載均衡的服務呼叫。
使用
修改article-service
,
新增依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
在註冊RestTemplate
方法上新增@LoadBalanced
註解開啟客戶端負載均衡,然後修改請求的URL,直接使用服務名請求,這裡能夠直接使用服務名,是因為在SpringCloudRibbon中有一個攔截器,他能夠在實際呼叫的時候自動的選取服務例項,並將實際請求的ip地址替換這裡的服務名。詳細介紹可以檢視DD大佬的書:<
@GetMapping("/a/u/{id}")
public User getUser(@PathVariable("id") Long id){
return restTemplate.getForObject("http://USER-SERVICE/user/{1}",User.class,id);
}
最後為了測試負載均衡,我們需要開啟多個USER-SERVICE服務例項;在USER-SERVICE中新增application-pree1.yml
和application-pree2.yml
,具體配與application.yml一樣,只要修改server.port
,這裡分別是40001和40002。然後打包服務,分別啟動兩個服務
java -jar user-0.0.1-SNAPSHOT.jar --spring.profiles.active=pree1
java -jar user-0.0.1-SNAPSHOT.jar --spring.profiles.active=pree2
在註冊中心可以看到三個USER-SERVICE服務:
最後啟動ARTICLE-SERVICE,並訪問介面。重新整理幾次頁面,發現三個服務都會列印資料庫語句,這裡呼叫方式為線性輪詢
Ribbon的配置
當我們在SpringBoot專案中新增SpringCloudRibbon以後,SpringBoot會為我們自動化配置Ribbon,有些時候自動化配置是無法滿足需要的。我們都知道在SpringBoot中我們可以使用兩種配置屬性的方法:使用java config方式和在配置檔案中配置。
使用配置類的方式
建立UserServiceConfig
,該類不能在啟動時候被掃描到,所以我們需要將該類放到SpringBoot入口類的上一層路徑下。
@Configuration
public class UserServiceConfig {
/**
*將服務檢查策略改為PingUrl
* @return
*/
@Bean
public IPing ribbonPing(){
return new PingUrl();
}
/**
* 將負載均衡的策略改為隨機選取服務例項
* @return
*/
@Bean
public IRule ribbonRule(){
return new RandomRule();
}
}
然後建立RibbonConfig
,這裡@RibbonClients
註解是可以指定多個RibbonClient,而@RibbonClient
註解則是指定那個哪個服務使用哪個配置類
@Configuration
@RibbonClients({
@RibbonClient(name = "user-service",configuration = UserServiceConfig.class),
})
public class RibbonConfig {
}
在appplication.yml中配置
在配置檔案中配置時候我們也可以配置全域性的和指定客戶端方式配置
1. 全域性配置,只需要使用ribbon.<key>=<value>
,key客戶端配置引數名,value為對應的引數值
2. 指定客戶端配置,使用<client>.ribbon.<key>=<value>
,這裡的client為指定的服務名。下面為user-service指定負載均衡策略:
USER-SERVICE:
ribbon:
RulePredicateClasses: com.netflix.loadbalancer.RandomRule
更多關於key的配置資訊可以檢視com.netflix.client.config.CommonClientConfigKey
。
作為SpringCloud學習筆記,可能有很多地方不好。望指出!!!