1. Feign應用
Feign的作用;使用Feign實現consumer-demo代碼中調用服務
- 導入啟動器依賴;
- 開啟Feign功能;
- 編寫Feign客戶端;
- 編寫一個處理器ConsumerFeignController,注入Feign客戶端并使用;
- 測試
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency>
@SpringCloudApplication
@EnableFeignClients
public class ConsumerApplication {public static void main(String[] args) {SpringApplication.run(ConsumerApplication.class, args);}@Bean@LoadBalancedpublic RestTemplate get(){return new RestTemplate();}
}
@FeignClient("user-service")
public interface UserClient {@GetMapping("/user/{id}")User get(@PathVariable long id);
}
@RestController
@RequestMapping("/cf")
public class ConsumerFeignController {@Autowiredprivate UserClient userClient;@GetMapping("/{id}")public User get(@PathVariable long id){return userClient.get(id);}
}
Feign主要作用:自動根據參數拼接http請求地址。
2. Feign負載均衡及熔斷
目標:可以配置Feign內置ribbon配置項和Hystrix熔斷的Fallback配置
分析:
- 負載均衡
- 服務熔斷
- 請求壓縮
- 日志級別
ribbon:ConnectTimeout: 1000 # 連接超時時長ReadTimeout: 2000 # 數據通信超時時長MaxAutoRetries: 0 # 當前服務器的重試次數MaxAutoRetriesNextServer: 0 # 重試多少次服務OkToRetryOnAllOperations: false # 是否對所有的請求方式都重試
feign:hystrix:enabled: true # 開啟Feign的熔斷功能compression:request:enabled: true # 開啟請求壓縮mime-types: text/html,application/xml,application/json # 設置壓縮的數據類型min-request-size: 2048 # 設置觸發壓縮的大小下限response:enabled: true
logging:level:com.gogo: debug
@Component
public class UserClientFallback implements UserClient{@Overridepublic User get(long id) {User user = new User();user.setId(id);user.setName("異常用戶");return user;}
}
@Configuration
public class FeignConfig {@BeanLogger.Level logLevel(){return Logger.Level.FULL;}}
@FeignClient(value = "user-service",fallback = UserClientFallback.class,configuration = FeignConfig.class)
public interface UserClient {@GetMapping("/user/{id}")User get(@PathVariable long id);
}
Spring Cloud Gateway的核心就是一系列的過濾器,可以將客戶端的請求轉發到不同的微服務。主要作用:過濾和路由。
4. Spring Cloud Gateway入門
需求:通過網關系統heima-gateway將包含有 /user 的請求 路由到 http://127.0.0.1:9091/user/用戶id
實現步驟:
- 創建工程;
- 添加啟動器依賴;
- 編寫啟動引導類和配置文件;
- 修改配置文件,設置路由信息;
- 啟動測試
<dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency></dependencies>
server:port: 10010
spring:application:name: api-gatewaycloud:gateway:routes:- id: user-service-routeuri: http://127.0.0.1:9091predicates:- Path=/user/**eureka:client:service-url:defaultZone: http://127.0.0.1:10086/eurekainstance:prefer-ip-address: true
5. 面向服務的路由
使用在eureka注冊的服務作為路由地址
如果將路由服務地址寫死明顯是不合理的;在Spring Cloud Gateway中可以通過配置動態路由解決。
面向服務的路由;只需要在配置文件中指定路由路徑類似: lb://user-service
lb 之后編寫的服務名必須要在eureka中注冊才能使用
server:port: 10010
spring:application:name: api-gatewaycloud:gateway:routes:- id: user-service-routeuri: lb://user-servicepredicates:- Path=/**filters:# 添加請求路徑的前綴- PrefixPath=/usereureka:client:service-url:defaultZone: http://127.0.0.1:10086/eurekainstance:prefer-ip-address: true
6. 路由前綴處理
可以對請求到網關服務的地址添加或去除前綴
提供服務的地址:http://127.0.0.1:9091/user/8
- 添加前綴:對請求地址添加前綴路徑之后再作為代理的服務地址;
http://127.0.0.1:10010/8 --> http://127.0.0.1:9091/user/8 添加前綴路徑/user
- 去除前綴:將請求地址中路徑去除一些前綴路徑之后再作為代理的服務地址;
http://127.0.0.1:10010/api/user/8 --> http://127.0.0.1:9091/user/8 去除前綴路徑/api
server:port: 10010
spring:application:name: api-gatewaycloud:gateway:routes:- id: user-service-routeuri: lb://user-servicepredicates:- Path=/**filters:# 添加請求路徑的前綴- PrefixPath=/usereureka:client:service-url:defaultZone: http://127.0.0.1:10086/eurekainstance:prefer-ip-address: true
filters:# 添加請求路徑的前綴- StripPrefix=1
客戶端的請求地址與微服務的服務地址如果不一致的時候,可以通過配置路徑過濾器實現路徑前綴的添加和去除。
7. 過濾器簡介
- 用法:在配置文件中指定要使用的過濾器名稱;
- 類型:局部、全局;
- 使用場景:請求鑒權、異常處理、記錄調用時長等。
8. 自定義局部過濾器
按照默認過濾器編寫并配置一個自定義局部過濾器,該過濾器可以通過配置文件中的參數名稱獲取請求的參數值
需求:在過濾器(MyParamGatewayFilterFactory)中將http://localhost:10010/api/user/8?name=itcast中的參數name的值獲取到并輸出到控制臺;并且參數名是可變的,也就是不一定每次都是name;需要可以通過配置過濾器的時候做到配置參數名。
實現步驟:
- 配置過濾器;
- 編寫過濾器;
- 測試
spring:application:name: api-gatewaycloud:gateway:routes:- id: user-service-routeuri: lb://user-servicepredicates:- Path=/api/user/**filters:# 添加請求路徑的前綴- StripPrefix=1- My=namedefault-filters:- AddResponseHeader=X-Response-Default-MyName, gogo
@Component
public class MyGatewayFilterFactory extends AbstractGatewayFilterFactory<MyGatewayFilterFactory.config> {public static final String PARAM_NAME = "param";@Overridepublic GatewayFilter apply(config config) {return ((exchange, chain) -> {ServerHttpRequest request = exchange.getRequest();if(request.getQueryParams().containsKey(config.param))request.getQueryParams().get(config.param).forEach(var-> System.out.println(config.param+var));return chain.filter(exchange);});}public MyGatewayFilterFactory() {super(config.class);}@Overridepublic List<String> shortcutFieldOrder() {return Arrays.asList(PARAM_NAME);}@Datapublic static class config{String param;}
}
9. 自定義全局過濾器
定義一個全局過濾器檢查請求中是否攜帶有token參數
需求:編寫全局過濾器,在過濾器中檢查請求地址是否攜帶token參數。如果token參數的值存在則放行;如果token的參數值為空或者不存在則設置返回的狀態碼為:未授權也不再執行下去。
實現步驟:
- 編寫全局過濾器;
- 測試
@Componentpublic class MyGlobalFilter implements GlobalFilter, Ordered {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {System.out.println("全局------------------");String token = exchange.getRequest().getQueryParams().getFirst("token");if(StringUtils.isBlank(token)){exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);return exchange.getResponse().setComplete();}return chain.filter(exchange);}@Overridepublic int getOrder() {return 1;}
}
10. Gateway其它配置說明
Gateway網關的負載均衡和熔斷參數配置
server:port: 10010
spring:application:name: api-gatewaycloud:gateway:routes:- id: user-service-routeuri: lb://user-servicepredicates:- Path=/api/user/**filters:# 添加請求路徑的前綴- StripPrefix=1- My=namedefault-filters:- AddResponseHeader=X-Response-Default-MyName, gogoglobalcors:corsConfigurations:'[/**]':#allowedOrigins: * # 這種寫法或者下面的都可以,*表示全部allowedOrigins:- "http://docs.spring.io"allowedMethods:- GETeureka:client:service-url:defaultZone: http://127.0.0.1:10086/eurekainstance:prefer-ip-address: truehystrix:command:default:execution:isolation:thread:timeoutInMilliseconds: 6000
ribbon:ConnectTimeout: 1000ReadTimeout: 2000MaxAutoRetries: 0MaxAutoRetriesNextServer: 0
Gateway網關一般直接給終端請求使用;Feign一般用在微服務之間調用。
11. Spring Cloud Config分布式配置中心簡介
目標:分布式配置中心的作用
小結:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Mg8yPP56-1614310505789)(assets/1560919656472.png)]
spring cloud config作用:可以通過修改在git倉庫中的配置文件實現其它所有微服務的配置文件的修改。
12. 搭建配置中心微服務
創建碼云的遠程公開git倉庫,搭建配置中心微服務config-server
-
創建git倉庫:在碼云上創建倉庫
-
搭建配置中心config-server:使用spring boot方式搭建和配置
-
配置中心依賴
<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-config-server</artifactId></dependency></dependencies>
- 配置中心的配置文件
eureka:client:service-url:defaultZone: http://127.0.0.1:10086/eurekainstance:prefer-ip-address: trueserver:port: 12000
spring:application:name: config-servercloud:config:server:git:uri: https://gitee.com/Gogo-gitee/config.git
在gitee中修改了配置文件會在配置中心服務及時更新。
13. 獲取配置中心配置
需求:將服務提供工程user-service的application.yml配置文件刪除,修改為從配置中心config-server中獲取。
實現步驟:
- 添加啟動器依賴;
- 修改配置文件;
- 啟動測試
將原來的application.yml刪除;然后添加bootstrap.yml配置文件,該文件也是spring boot的默認配置文件,其內容經常配置一些項目中固定的配置項。如果是項目經常變動的應該配置到application.yml中,現在使用了配置中心則應該配置到git倉庫中對于的配置文件。
- 依賴
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-config</artifactId><version>2.1.1.RELEASE</version></dependency>
- 配置文件bootstrap.yml
spring:cloud:config:# 要與倉庫中的配置文件的application保持一致name: user# 要與倉庫中的配置文件的profile保持一致profile: dev# 要與倉庫中的配置文件所屬的版本(分支)一樣label: masterdiscovery:# 使用配置中心enabled: true# 配置中心服務名service-id: config-servereureka:client:service-url:defaultZone: http://127.0.0.1:10086/eureka
14. Spring Cloud Bus簡介
目標:了解Spring Cloud Bus作用
小結:
Spring Cloud Bus作用:將git倉庫的配置文件更新,在不重啟系統的情況下實現及時同步到各個微服務。
15. Spring Cloud Bus應用
需求:在碼云的git倉庫中修改user-dev.yml配置文件,實現不重啟user-service的情況下可以及時更新配置文件。
實現步驟:
- 啟動RabbitMQ;
- 修改配置中心config-server;
- 修改服務提供工程user-service;
- 測試
- config-server的依賴添加內容
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-bus</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-stream-binder-rabbit</artifactId></dependency>
- config-server的配置文件添加內容
server:port: 12000
spring:application:name: config-servercloud:config:server:git:uri: https://gitee.com/goheima/heima-config.git# 配置rabbitmq信息;如果是都與默認值一致則不需要配置rabbitmq:host: localhostport: 5672username: guestpassword: guest
eureka:client:service-url:defaultZone: http://127.0.0.1:10086/eureka
management:endpoints:web:exposure:# 暴露觸發消息總線的地址include: bus-refresh
- user-service的依賴添加內容
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-bus</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-stream-binder-rabbit</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency>
- user-service的配置文件添加內容
# 配置rabbitmq信息;如果是都與默認值一致則不需要配置rabbitmq:host: localhostport: 5672username: guestpassword: guest
- UserController的修改
@RestController
@RefreshScope
public class HelloController {@Autowiredprivate DataSource dataSource;@AutowiredUserService userService;@Value("${test}")private String test;@GetMapping("/user/{id}")public User query(@PathVariable long id){return userService.queryId(id);}@GetMapping("/hello")public String hello(){return "hello "+test;}
}