系列文章目錄
第一章 Java線程池技術(shù)應(yīng)用
第二章 CountDownLatch和Semaphone的應(yīng)用
第三章 Spring Cloud 簡(jiǎn)介
第四章 Spring Cloud Netflix 之 Eureka
第五章 Spring Cloud Netflix 之 Ribbon
前言
Spring Cloud Ribbon 是一套基于 Netflix Ribbon 實(shí)現(xiàn)的客戶端負(fù)載均衡和服務(wù)調(diào)用工具,其主要功能是提供客戶端的負(fù)載均衡算法和服務(wù)調(diào)用。
今天我們以電商微服務(wù)為例,來講解Eureka 、Ribbon在微服務(wù)治理方面的實(shí)戰(zhàn)應(yīng)用。
1、負(fù)載均衡
負(fù)載均衡(Load Balance) ,簡(jiǎn)單點(diǎn)說就是將用戶的請(qǐng)求平攤分配到多個(gè)服務(wù)器上運(yùn)行,以達(dá)到擴(kuò)展服務(wù)器帶寬、增強(qiáng)數(shù)據(jù)處理能力、增加吞吐量、提高網(wǎng)絡(luò)的可用性和靈活性的目的。
常見的負(fù)載均衡方式有兩種:服務(wù)端負(fù)載均衡、客戶端負(fù)載均衡
1.1、服務(wù)端負(fù)載均衡
1.2、客戶端負(fù)載均衡
2、Ribbon實(shí)現(xiàn)服務(wù)間調(diào)用
Ribbon 可以與 RestTemplate(Rest 模板)配合使用,以實(shí)現(xiàn)微服務(wù)之間的調(diào)用
示例:
建立C端API工程customer-api
2.1、pom.xml配置
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.hqyj</groupId>
<artifactId>SpringCloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>customer-api</artifactId>
<name>customer-api</name>
<description>customer-api</description>
<properties>
<java.version>1.8</java.version>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--devtools 開發(fā)工具-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!--Spring Boot 測(cè)試-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--junit 測(cè)試-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!-- 修改后立即生效,熱部署 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
<version>1.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>com.hqyj</groupId>
<artifactId>common-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
2.2、application.yml配置
server:
port: 80
eureka:
client:
register-with-eureka: false #本微服務(wù)為服務(wù)消費(fèi)者,不需要將自己注冊(cè)到服務(wù)注冊(cè)中心
fetch-registry: true #本微服務(wù)為服務(wù)消費(fèi)者,需要到服務(wù)注冊(cè)中心搜索服務(wù)
service-url:
defaultZone: http://localhost:7001/eureka
2.3、bean配置類
配置RestTemplate、開啟負(fù)載均衡
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
/***
* @title bean配置類
* @desctption 配置RestTemplate、開啟負(fù)載均衡
* @author kelvin
* @create 2023/5/11 14:33
**/
@Configuration
public class ConfigBean {
@Bean //將 RestTemplate 注入到容器中
@LoadBalanced //在客戶端使用 RestTemplate 請(qǐng)求服務(wù)端時(shí),開啟負(fù)載均衡(Ribbon)
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}
2.4、編寫調(diào)用Eureka的代碼
2.4.1、定義用戶服務(wù)接口
import com.hqyj.common.model.UserInfo;
import java.util.List;
/***
* @title 用戶服務(wù) 接口
* @desctption 用戶服務(wù)
* @author kelvin
* @create 2023/5/11 14:22
**/
public interface UserConsumerService {
/**
* 獲取用戶信息列表
* @return
*/
public List<UserInfo> userInfoList();
}
2.4.2、編寫用戶服務(wù)實(shí)現(xiàn)類
import com.hqyj.common.model.UserInfo;
import com.hqyj.customerapi.service.UserConsumerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.List;
/***
* @title 用戶服務(wù) 實(shí)現(xiàn)類
* @desctption 用戶服務(wù)
* @author kelvin
* @create 2023/5/11 14:22
**/
@Service
public class UserConsumerServiceImpl implements UserConsumerService {
private String REST_URL_PROVIDER_PREFIX = "http://USER-SERVICE";
@Autowired
private RestTemplate restTemplate;
/**
* 獲取用戶信息列表
* @return
*/
@Override
public List<UserInfo> userInfoList() {
return this.restTemplate.getForObject(this.REST_URL_PROVIDER_PREFIX + "/user/userInfoList",List.class);
}
}
2.4.3、編寫用戶服務(wù)控制層代碼
import com.hqyj.common.model.UserInfo;
import com.hqyj.customerapi.service.UserConsumerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/***
* @title UserConsumerController
* @desctption 用戶控制層
* @author kelvin
* @create 2023/5/11 14:22
**/
@RestController
@RequestMapping("/user")
public class UserConsumerController {
@Autowired
private UserConsumerService userConsumerService;
@GetMapping("/userInfoList")
public List<UserInfo> userInfoList(){
return userConsumerService.userInfoList();
}
}
2.4.4、統(tǒng)一返回結(jié)果
在公共模塊common-api里面添加DTO
import lombok.Data;
/***
* @title 統(tǒng)一返回格式類
* @param <T>
* @desctption 統(tǒng)一返回格式
* @author kelvin
* @create 2023/5/11 14:28
**/
@Data
public class ResponseDTO<T> {
/**
* 返回編碼
*/
private Integer code;
/**
* 統(tǒng)一返回消息
*/
private String message;
/**
* 統(tǒng)一返回?cái)?shù)據(jù)體
*/
private T data;
}
2.4.5、統(tǒng)一異常處理
實(shí)現(xiàn) ResponseBodyAdvice接口
import com.hqyj.common.dto.ResponseDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
/***
* @title 統(tǒng)一異常處理類
* @desctption 統(tǒng)一異常處理
* @author kelvin
* @create 2023/5/11 14:33
**/
@RestControllerAdvice(basePackages = "com.hqyj.customerapi.controller")
@Slf4j
public class ControllerResponseAdvice implements ResponseBodyAdvice<Object> {
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
//true為織入通知
return true;
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
ResponseDTO<Object> objectResponseDTO = new ResponseDTO<>();
objectResponseDTO.setCode(200);
objectResponseDTO.setData(body);
return objectResponseDTO;
}
/**
* 統(tǒng)一異常處理
* @param e
* @return
*/
@ExceptionHandler(value = Exception.class)
public Object exception(Exception e){
log.error("系統(tǒng)異常",e);
ResponseDTO<Object> objectResponseDTO = new ResponseDTO<>();
objectResponseDTO.setCode(500);
objectResponseDTO.setMessage("系統(tǒng)異常");
return objectResponseDTO;
}
}
2.5、啟動(dòng)項(xiàng)目,訪問接口
2.5.1、啟動(dòng)項(xiàng)目
需要上一章節(jié)的2個(gè)項(xiàng)目先運(yùn)行
2.5.2、訪問接口
訪問地址:http://localhost/user/userInfoList文章來源:http://www.zghlxwxcb.cn/news/detail-713110.html
總結(jié)
在以前的分布式項(xiàng)目里,我們使用zookeeper、redis等來存放服務(wù)注冊(cè)信息,在客戶端調(diào)用服務(wù)時(shí),需要自己手動(dòng)獲取可用服務(wù)清單,使用起來非常麻煩,對(duì)初級(jí)開發(fā)人員特別不友好,一不小心就犯錯(cuò),比如zookeeper依賴版本沖突、zookeeper\redis集群地址填寫錯(cuò)誤、zookeeper\redis配置項(xiàng)缺失等。
Ribbon的出現(xiàn)解決了上述部分問題,而且Ribbon屬于Netflix生態(tài)里的組件,與Eureka可以很好的集成起來組合使用,非常方便。文章來源地址http://www.zghlxwxcb.cn/news/detail-713110.html
到了這里,關(guān)于云原生微服務(wù) 第五章 Spring Cloud Netflix Eureka集成負(fù)載均衡組件Ribbon的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!