日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

SpringCloud微服务架构,Spring Cloud 服务治理(Eureka,Consul,Nacos),Ribbon 客户端负载均衡,RestTemplate与OpenFeign实现远程调用

發布時間:2024/4/15 javascript 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SpringCloud微服务架构,Spring Cloud 服务治理(Eureka,Consul,Nacos),Ribbon 客户端负载均衡,RestTemplate与OpenFeign实现远程调用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

什么是SpringCloud

微服務架構
? "微服務”一詞源于 Martin Fowler的名為 Microservices的博文,可以在他的官方博客上找到
http://martinfowler.com/articles/microservices.html
? 微服務是系統架構上的一種設計風格,它的主旨是將一個原本獨立的系統拆分成多個小型服務,這些小型服務都在各自獨立的進程中運行,服務之間一般通過 HTTP 的 RESTfuLAPI 進行通信協作。
? 被拆分成的每一個小型服務都圍繞著系統中的某一項或些耦合度較高的業務功能進行構建,并且每個服務都維護著白身的數據存儲、業務開發自動化測試案例以及獨立部署機制。
? 由于有了輕量級的通信協作基礎,所以這些微服務可以使用不同的語言來編寫。

定義:是一些列組件的集合
組件:

  • 注冊中心
  • 配置中心
  • 熔斷器
  • 網關
  • 負載均衡
  • 消息總線
  • 數據監控

SpringCloud與Dubbo的區別

  • Dubbo是基于RPC協議實現遠程調用的,同時要求所用語言必須是Java
  • SpringCloud規定服務之間通過http協議進行通信
  • Dubbo性能較好(因為底層基于socket),SpringCloud功能全

SpringCloud 服務治理(詳細解釋在代碼注釋中)

服務注冊與發現

Eureka

? Eureka 是 Netflix 公司開源的一個服務注冊與發現的組件 。
? Eureka 和其他 Netflix 公司的服務組件(例如負載均衡、熔斷器、網關等) 一起,被 Spring Cloud 社區整合為
Spring-Cloud-Netflix 模塊。
? Eureka 包含兩個組件:Eureka Server (注冊中心) 和 Eureka Client (服務提供者、服務消費者)。

Eureka – 搭建服務

搭建eureka服務,編寫provider服務提供者,編寫consumer服務消費者端,并將服務注冊到eureka注冊中心,使用Ribbon實現負載均衡

這些簡單的實體類與返回的結果集就不粘貼出來了,主要看eureka搭建后的效果

父pom.xml
pom文件中包含一些nacos,OpenFeign后面會用

<?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"><modelVersion>4.0.0</modelVersion><groupId>com.fs</groupId><artifactId>study-springcloud</artifactId><version>1.0-SNAPSHOT</version><modules><module>fs-provider-8001</module><module>fs-consumer-80</module><module>fs-server-eureka-7001</module><module>fs-api-commons</module><module>fs-server-eureka-7002</module><module>fs-server-eureka-7003</module><module>fs-provider-nacos-8001</module><module>fs-consumer-nacos-80</module><module>fs-provider-8002</module><module>fs-consumer-openFeign-80</module></modules><!-- 作為父工程--><packaging>pom</packaging><dependencyManagement><dependencies><!-- spring boot --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>2.3.2.RELEASE</version><type>pom</type> <!-- import 導入父工程的配置--><scope>import</scope></dependency><!-- spring cloud --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>Hoxton.SR6</version><type>pom</type> <!-- import 導入父工程的配置--><scope>import</scope></dependency><!-- spring-cloud-alibaba-dependencies 2.2.1.RELEASE --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>2.2.1.RELEASE</version><type>pom</type><scope>import</scope></dependency><!-- eureka-server --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId><version>2.2.4.RELEASE</version></dependency><!-- eureka-client --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId><version>2.2.4.RELEASE</version></dependency><!-- 整合MyBatis--><!-- mysql --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.20</version><scope>runtime</scope></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.1.20</version></dependency><!-- MyBatisPlus --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.3.2</version></dependency> <!-- lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.12</version></dependency></dependencies></dependencyManagement><dependencies></dependencies></project>

搭建 Provider 和 Consumer 服務。

Provider 創建 fs-provider-8001 項目

多個提供復制一下,然后更改端口號與application.yml中配置注冊的注冊中心即可
我只粘貼出application.yml,pom.xml,主啟動,與服務提供的controller,因為dao,service就是使用了MyBatis-plus

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 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>study-springcloud</artifactId><groupId>com.fs</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>fs-provider-8001</artifactId><dependencies><!-- spring-boot-starter-web spring-boot-starter-actuator綁定在一塊 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- eureka-Client--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId><!-- 第一種是:如果你的應用不會再需要返回xml的系列化格式,那么直接在pom.xml文件中將jackson-dataformat-xml這外包排除即可(如果其他包也進行了jackson-dataformat-xml的依賴引用也要視情況排除):第二種是:不排除jackson-dataformat-xml包,而是直接在相應接口方法或Controller上明確指定將返回JSON格式的值:@GetMapping(value = "/user-instance", produces = MediaType.APPLICATION_PROBLEM_JSON_VALUE) --> <!-- 排除controller返回的格式為xml--><exclusions><exclusion><groupId>com.fasterxml.jackson.dataformat</groupId><artifactId>jackson-dataformat-xml</artifactId></exclusion></exclusions></dependency><!-- mysql--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency> <!-- jdbc--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency> <!-- druid--><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId></dependency> <!-- MyBatis-puls--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId></dependency><!-- 自己的實體類--><dependency><groupId>com.fs</groupId><artifactId>fs-api-commons</artifactId><version>1.0-SNAPSHOT</version></dependency></dependencies> </project>

application.yml

搭建集群provider集群就把 server.prot改下,吧defaultZone:多個地址用逗號隔開
注意的是,域名記得在host文件中修改域名與端口的映射

server:port: 8001 spring:application:name: fs-providerdatasource:username: rootpassword: rooturl: jdbc:mysql://192.168.93.132:3306/fs_springclouddriver-class-name: com.mysql.cj.jdbc.Drivertype: com.alibaba.druid.pool.DruidDataSource #自定義數據源# 配置eureka eureka:instance:hostname: localhost # 主機名,寫的是域名,本機在host文件中映射prefer-ip-address: true # 將當前實例的ip注冊到eureka server中.默認是false 注冊主機名ip-address: 127.0.0.1 # 修改instance-id顯示 # # 修改instance-id顯示,在eureka中的顯示名稱 # instance-id: ${eureka.instance.ip-address}:${spring.application.name}:${server.port} # lease-renewal-interval-in-seconds: 30 # 每一次eureka client 向 eureka server發送心跳的時間間隔 # lease-expiration-duration-in-seconds: 90 # 如果90秒內eureka server沒有收到eureka client的心跳包,則剔除該服務client:register-with-eureka: true # 將提供注冊到注冊eureka中心fetch-registry: true # 從eureka上抓取已有的注冊信息service-url:defaultZone: http://localhost:7001/eureka #,http://localhost2:7002/eureka,http://localhost3:7003/eureka # 注冊中心地址# 配置MyBatis-plus日志 mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

FsProvider8001主啟動

package com.fs;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient;@SpringBootApplication //開啟Eureka客戶端 @EnableEurekaClient public class FsProvider8001 {public static void main(String[] args) {SpringApplication.run(FsProvider8001.class,args);} }

PaymentController

package com.fs.controller;import com.fs.pojo.Payment; import com.fs.result.Result; import com.fs.service.PaymentService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;import java.util.List; import java.util.concurrent.TimeUnit;@RestController @RequestMapping("/payment") public class PaymentController {//注入業務層@Autowiredprivate PaymentService paymentService;@RequestMapping("/findAll")public Result<List<Payment>> findAll(){List<Payment> all = paymentService.findAll();return new Result<List<Payment>>(true,"查詢成功8001",all);}@RequestMapping("/testTimeOut")public Result test(){try {//讓方法停止2秒,模擬方法執行時間過長,因為Ribbon的超時時間默認為1秒,超時就會報錯TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {e.printStackTrace();}return new Result<List<Payment>>(true,"查詢成功");}}

Consumer 創建 fs-consumer-80 消費者 使用 RestTemplate 完成遠程調用。

Resttemplate

? Spring提供的一種簡單便捷的模板類,用于在 java 代碼里訪問 restful 服務。
? 其功能與 HttpClient 類似,但是 RestTemplate 實現更優雅,使用更方便。

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 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>study-springcloud</artifactId><groupId>com.fs</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>fs-consumer-80</artifactId><dependencies><!-- spring-boot-starter-web spring-boot-starter-actuator綁定在一塊 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- eureka-Client--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId><!-- 排除controller返回的格式為xml--><exclusions><exclusion><groupId>com.fasterxml.jackson.dataformat</groupId><artifactId>jackson-dataformat-xml</artifactId></exclusion></exclusions></dependency><!-- 自己的實體類--><dependency><groupId>com.fs</groupId><artifactId>fs-api-commons</artifactId><version>1.0-SNAPSHOT</version></dependency></dependencies></project>

application.yml

server:port: 80spring:application:name: fs-consumer-80 eureka:client:register-with-eureka: false # 消費者我目前的用途不需要將消費者注冊到注冊中心fetch-registry: true # 從注冊中心拉取服務registry-fetch-interval-seconds: 30 # 默認30秒定時去注冊中心拉取服務service-url:defaultZone: http://localhost:7001/eureka #,http://localhost2:7002/eureka,http://localhost3:7003/eureka # 注冊中心地址# 配置的方式設置Ribbon的負載均衡 #FS-PROVIDER: # 設置的我們服務提供方的應用名稱 # ribbon: # 固定寫法 # NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #負載均衡的規則,表示加權規則,yml配置優先級第一,Java代碼第二,默認的最后# 自定義屬性來存儲注冊中心 提供者的名字 provider:name: FS-PROVIDER

主啟動 FsConsumer80

package com.fs;import com.fs.config.MyRule; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.cloud.netflix.ribbon.RibbonClient;@SpringBootApplication @EnableEurekaClient @EnableDiscoveryClient //激活發現客戶端 //開啟客戶端負載均衡,不使用默認的輪詢, //name 設置我們這個負載均衡用于那個服務提供方 configuration 使用我們自定義的配置類中配置的負載均衡 @RibbonClient(name = "FS-PROVIDER",configuration = MyRule.class) public class FsConsumer80 {public static void main(String[] args) {SpringApplication.run(FsConsumer80.class,args);} }

MyRule 定義負載均衡策略

== Ribbon負載均衡器==

  • 定義:解決客戶端的服務負載均衡算法處理器

  • 功能:

    • 負載均衡
    • 簡化遠程調用過程
  • 使用:

    • 開啟負載均衡功能(默認輪詢策略)

      @LoadBanlance
    • 修改主機名為服務名

      http://服務名稱/login
  • 怎么修改負載均衡策略

    • 注解方式

      ### xxx 是一個JavaConfig類,其中?配置使用的策略Bean @RibbonClient(name="",configuration = XXX.Class)
    • 配置方式

      [服務名稱1]:ribbon:NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule [服務名稱2]:ribbon:NFLoadBalancerRuleClassName: com.netflix.loadbalancer.BestAvailableRule
MyRule
package com.fs.config;import com.netflix.loadbalancer.IRule; import com.netflix.loadbalancer.RandomRule; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;/* 編碼的方式設置 定義Ribbon負載均衡的配置類注意:這個類不能在@Configuration 下的@@ComponentScan掃描的包下因為@SpringBootApplication這個注解定義為掃描被這個注解注解的類的包及其子包所以,我們這個Ribbon負載均衡的配置類就只能從新新建一個包,不在主配置類包下及其子包就可以了這里配置為隨機后記得在主啟動類上加上一個注解@RibbonClient*/ @Configuration public class MyRule {@Beanpublic IRule myIRule(){//import com.netflix.loadbalancer.RandomRule;這個類就就代表負載均衡為隨機//創建負載均衡的策略為隨機RandomRule randomRule = new RandomRule();return randomRule;} }

RestTemplateConfig 注入RestTemplate

package com.fs.config;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;/* 定義restTemplate*/ @Configuration public class RestTemplateConfig {@Bean//客戶端負載均衡@LoadBalanced //使用默認的負載均衡輪詢public RestTemplate restTemplate(){return new RestTemplate();} }

PaymentController 服務消費者

package com.fs.controller;import com.fs.pojo.Payment; import com.fs.result.Result; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate;import java.util.List;@RestController @RequestMapping("/consumer") public class PaymentController {//注入RestTemplate@Autowiredprivate RestTemplate restTemplate;//注入DiscoveryClient,動態從eureka server 中獲取 provider 的host與ip@Autowiredprivate DiscoveryClient discoveryClient;// String host; // int port;// private String PAYMENT_URL ="http://"+host+ ":"+port;//從application.yml文件中讀取@Value("${provider.name}")private String providerName;@RequestMapping("/payment/findAll")public Result<List<Payment>> findAll(){//搭建集群后,使用服務名稱做url,負載均衡的調用注冊中心的服務Result<List<Payment>> result = restTemplate.getForObject("http://"+providerName+"/payment/findAll", Result.class);return result;}// @RequestMapping("/payment/findAll") // public Result<List<Payment>> findAll(){ // //得到服務的實體,為什么是集合呢?因為未來的一個微服務名稱是搭建集群的 // List<ServiceInstance> instances = discoveryClient.getInstances("FS-PROVIDER"); // String host = null; // int port = 0; // // if (instances.size()>0){ // //獲取第一個 // ServiceInstance serviceInstance = instances.get(0); // //見名知意 // host = serviceInstance.getHost(); // port = serviceInstance.getPort(); // }else { // return null; // } // Result<List<Payment>> result = restTemplate.getForObject("http://"+host+":"+port+"/payment/findAll", Result.class); // result.setMessage(host+":"+port); // return result; // } }

搭建 Eureka Server 服務。

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 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>study-springcloud</artifactId><groupId>com.fs</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>fs-server-eureka-7001</artifactId><dependencies><!-- eureka-server --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency><!-- spring-boot-starter-web spring-boot-starter-actuator綁定在一塊 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies></project>

application.yml

server:port: 7001 spring:application:name: fs-server-eureka-ha eureka:instance:hostname: localhost #主機名,域名,本機在host文件配置client:register-with-eureka: false # 是否將自己注冊到eureka,搭建繼續需要將eurekaserver注冊到注冊中心,相互注冊fetch-registry: false # 是否從EurekaServer抓取已有的注冊信息service-url:defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka# eureka集群 # client: # register-with-eureka: true # 是否將自己注冊到eureka,搭建繼續需要將eurekaserver注冊到注冊中心,相互注冊 # fetch-registry: true # 是否從EurekaServer抓取已有的注冊信息 # service-url: # defaultZone: http://localhost2:7002/eureka,http://localhost3:7003/eureka # server: # enable-self-preservation: false # 默認true 開啟自我保護機制,但是開發中可以關掉,方便開發,實際生產一定使用默認的true # eviction-interval-timer-in-ms: 3000 #默認60秒

主啟動 ServerEureka7001

package com.fs;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;@SpringBootApplication //開啟eureka的服務 @EnableEurekaServer public class ServerEureka7001 {public static void main(String[] args) {SpringApplication.run(ServerEureka7001.class,args);} }

測試Eureka – 搭建服務

啟動ServerEureka7001
啟動FsProvider8001
啟動FsConsumer80

瀏覽器分別打開:
http://localhost:7001/

http://localhost:8001/payment/findAll

http://localhost/consumer/payment/findAll
通過消費端使用RestTemplate遠程調用我們的服務提供者

Eureka – 相關配置及特性

- instance

eureka:instance:hostname: localhost # 主機名client:service-url:defaultZone: http://localhost:8761/eureka # eureka服務端地址,將來客戶端使用該地址和eureka進行通信register-with-eureka: true # 是否將自己的路徑 注冊到eureka上。eureka server 不需要的,eureka provider client 需要fetch-registry: true # 是否需要從eureka中抓取路徑。eureka server 不需要的,eureka consumer client 需要

- server

eureka:server:#是否開啟自我保護機制,默認trueenable-self-preservation:#清理間隔(單位毫秒,默認是60*1000)eviction-interval-timer-in-ms:instance:lease-renewal-interval-in-seconds: 30 # 每一次eureka client 向 eureka server發送心跳的時間間隔lease-expiration-duration-in-seconds: 90 # 如果90秒內eureka server沒有收到eureka client的心跳包,則剔除該服務

- client

eureka:client:service-url:# eureka服務端地址,將來客戶端使用該地址和eureka進行通信defaultZone:register-with-eureka: # 是否將自己的路徑 注冊到eureka上。fetch-registry: # 是否需要從eureka中抓取數據。

- dashboard

eureka:dashboard:enabled: true # 是否啟用eureka web控制臺path: / # 設置eureka web控制臺默認訪問路徑

Consul客戶端配置(了解,不常用)

  • 服務ip和地址
  • 服務名稱
    換湯不換藥,總的使用差不多
    ? Consul 是由 HashiCorp 基于 Go 語言開發的,支持多數據中心,分布式高可用的服務發布和注冊服務軟件。
    ? 用于實現分布式系統的服務發現與配置。
    ? 使用起來也較 為簡單。具有天然可移植性(支持Linux、windows和Mac OS X);安裝包僅包含一個可執行文件,
    方便部署 。
    ? 官網地址: https://www.consul.io
spring:cloud:consul:host: localhost # consul 服務端的 ipport: 8500 # consul 服務端的端口 默認8500discovery:service-name: ${spring.application.name} # 當前應用注冊到consul的名稱prefer-ip-address: true # 注冊ipapplication:name: consul-provider # 應用名稱

OpenFeign

什么是Feign

  • 定義:是微服務之間通過http協議調用的簡化使用的框架

  • 事實:

    • Feign自動集成Ribbon,且默認開啟相關功能
  • 使用:

    • 導包

      <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
    • 配置
      這個配置信息可以在springboot的項目idea按兩下shitf,輸入feign**properties(****properties)這樣的類中都可以發現這個類有哪些配置可以在yml配置文件中配置

      ribbon:ConnectTimeout: 1000 # 連接超時時間 默認1sReadTimeout: 3000 # 邏輯處理的超時時間 默認1s
    • 編碼

      • 開啟Feign功能

        @EnableFeignClients
      • 編寫Feign接口

        // 指定當前類的方法都從Eureka中對應的服務去調用 @FeignClient("服務的名稱") public interface ProviderService {// 通過Controller的地址映射注解告訴Feign該類findOne2方法從服務提供者的/findOne/{id}地址獲取信息// 通過Controller的參數獲取注解告訴Feign的參數信息// 通過返回值告訴Feign應該返回的參數應該封裝的格式@GetMapping("/goods/findOne/{id}")public Goods findOne(@PathVariable("id") int id);}

SpringBoot開啟DEBUG日志

  • 開啟SpringBoot框架的DEBUG日志

    • 開啟全部

      # 設置當前的日志級別 debug,feign只支持記錄debug級別的日志 logging:level:root: debug
    • 開啟部分

      logging:level:com.fs: debug
  • 開啟Feign的日志

    • 必須開啟對應Feign接口包的日志為DEBUG

    • 編碼

      • 定義日志級別

        @Configuration public class FeignLogConfig {/*NONE,不記錄BASIC,記錄基本的請求行,響應狀態碼數據HEADERS,記錄基本的請求行,響應狀態碼數據,記錄響應頭信息FULL;記錄完成的請求 響應數據*/@Beanpublic Logger.Level level(){return Logger.Level.FULL;} }
      • 配置生效

        @FeignClient(value = "FEIGN-PROVIDER",configuration = FeignLogConfig.class)

Nacos客戶端配置 基于OpenFeign遠程調用(代碼中詳細注釋)

? Nacos(Dynamic Naming and Configuration Service) 是阿里巴巴2018年7月開源的項目。
? 它專注于服務發現和配置管理領域 致力于幫助您發現、配置和管理微服務。Nacos 支持幾乎所有主流類型的“服務”的發現、配置和管理。
? 一句話概括就是Nacos = Spring Cloud注冊中心 + Spring Cloud配置中心。
? 官網:https://nacos.io/
? 下載地址: https://github.com/alibaba/nacos/releases

docker安裝nacos

#1.3.2 # 創建 /home/dockerdata/nacos/logs目錄用于掛載# 拉取nacos鏡像 docker pull nacos/nacos-server:1.3.2 # 運行容器 這里面的sql語句需要在github的nacos中去拷貝執行 執行成功后訪問ip:端口/nacos docker run -d \ -e PREFER_HOST_MODE=ip \ -e MODE=standalone \ -e SPRING_DATASOURCE_PLATFORM=mysql \ -e MYSQL_SERVICE_HOST=47.112.174.148 \ -e MYSQL_SERVICE_PORT=3306 \ -e MYSQL_SERVICE_USER=root \ -e MYSQL_SERVICE_PASSWORD=root \ -e MYSQL_SERVICE_DB_NAME=nacos \ -e TIME_ZONE='Asia/Shanghai' \ -v /docker/dockerdata/nacos/logs:/home/nacos/logs \ -p 8848:8848 \ --name nacos1.3.2 \ --restart=always \ nacos/nacos-server:1.3.2# 意思 docker run -d \ -e PREFER_HOST_MODE=hostname \ -e MODE=standalone \ -e SPRING_DATASOURCE_PLATFORM=mysql \ -e MYSQL_MASTER_SERVICE_HOST=數據庫ip \ -e MYSQL_MASTER_SERVICE_PORT=數據庫端口 \ -e MYSQL_MASTER_SERVICE_USER=用戶名 \ -e MYSQL_MASTER_SERVICE_PASSWORD=密碼 \ -e MYSQL_MASTER_SERVICE_DB_NAME=對應的數據庫名 \ -e MYSQL_SLAVE_SERVICE_HOST=從數據庫ip \ -p 8848:8848 \ --name nacos-sa-mysql \ --restart=always \ nacos/nacos-server

使用上面的父項目搭建

fs-provider-nacos-8001 服務提供端

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 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>study-springcloud</artifactId><groupId>com.fs</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>fs-provider-nacos-8001</artifactId><dependencies><!-- springcloud alibaba nacos--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!--這兩個spring-cloud-starter-alibaba-nacos-discovery都可以--><!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-alibaba-nacos-discovery --> <!-- <dependency>--> <!-- <groupId>org.springframework.cloud</groupId>--> <!-- <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>--> <!-- <version>0.9.0.RELEASE</version>--> <!-- </dependency>--><!-- https://mvnrepository.com/artifact/com.alibaba.nacos/nacos-client --><dependency><groupId>com.alibaba.nacos</groupId><artifactId>nacos-client</artifactId><version>1.3.2</version></dependency><!-- spring-boot-starter-web spring-boot-starter-actuator綁定在一塊 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- mysql--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!-- jdbc--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><!-- druid--><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId></dependency><!-- MyBatis-puls--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId></dependency><!-- 自己的實體類--><dependency><groupId>com.fs</groupId><artifactId>fs-api-commons</artifactId><version>1.0-SNAPSHOT</version></dependency></dependencies></project>

application.yml

server:port: 8001 spring:application:name: fs-provider-nacosdatasource:username: rootpassword: rooturl: jdbc:mysql://192.168.93.132:3306/fs_springclouddriver-class-name: com.mysql.cj.jdbc.Drivertype: com.alibaba.druid.pool.DruidDataSource #自定義數據源# 將服務提供者注冊到nacos注冊中心cloud:nacos:discovery:server-addr: 192.168.93.132:8848 # 配置nacos 服務端地址# 配置MyBatis-plus日志 mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

主啟動 FsNacosProvider8001

package com.fs;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication public class FsNacosProvider8001 {public static void main(String[] args) {SpringApplication.run(FsNacosProvider8001.class,args);} }

PaymentController 服務提供controller

package com.fs.controller;import com.fs.pojo.Payment; import com.fs.result.Result; import com.fs.service.PaymentService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;import java.util.List; import java.util.concurrent.TimeUnit;@RestController @RequestMapping("/payment") public class PaymentController {//注入業務層@Autowiredprivate PaymentService paymentService;@RequestMapping("/findAll")public Result<List<Payment>> findAll(){List<Payment> all = paymentService.findAll();return new Result<List<Payment>>(true,"查詢成功nacos8001",all);}@RequestMapping("/testTimeOut")public Result test(){try {//讓方法停止2秒,模擬方法執行時間過長,因為Ribbon的超時時間默認為1秒,超時就會報錯TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {e.printStackTrace();}return new Result<List<Payment>>(true,"查詢成功");} }

fs-consumer-nacos-80 服務消費端

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 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>study-springcloud</artifactId><groupId>com.fs</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>fs-consumer-nacos-80</artifactId><dependencies><!-- springcloud alibaba nacos--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!--這兩個spring-cloud-starter-alibaba-nacos-discovery都可以--><!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-alibaba-nacos-discovery --><!-- <dependency>--><!-- <groupId>org.springframework.cloud</groupId>--><!-- <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>--><!-- <version>0.9.0.RELEASE</version>--><!-- </dependency>--><!-- https://mvnrepository.com/artifact/com.alibaba.nacos/nacos-client --><dependency><groupId>com.alibaba.nacos</groupId><artifactId>nacos-client</artifactId><version>1.3.2</version></dependency><!-- openFeign--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><!-- spring-boot-starter-web spring-boot-starter-actuator綁定在一塊 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- 自己的實體類--><dependency><groupId>com.fs</groupId><artifactId>fs-api-commons</artifactId><version>1.0-SNAPSHOT</version></dependency></dependencies></project>

application.yml

server:port: 80spring:application:name: fs-consumer-nacoscloud:nacos:discovery:server-addr: 192.168.93.132:8848 # 配置nacos 服務端地址logging:level:# root: debug # 開啟springboot的debug的日志信息,不配置springboot默認是info# com.fs: debug # 開啟部分springboot的debug的日志信息# feign日志以什么級別監控那個feign組件功能使用的接口,使用debug級別(只能記錄debug級別),然后調用服務方法,在控制臺就能看到詳細debug信息com.fs.springcloud.server.PaymentOpenFeignService: debug

主啟動 FsNacosConsumer80

package com.fs;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.openfeign.EnableFeignClients;@SpringBootApplication //開啟OpenFeign @EnableFeignClients public class FsNacosConsumer80 {public static void main(String[] args) {SpringApplication.run(FsNacosConsumer80.class,args);} }

OpenFeignConfig

package com.fs.config;import feign.Logger; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;/* OpenFeign的日志配置類*/ @Configuration public class OpenFeignConfig {@BeanLogger.Level feignLoggerLevel(){//表示開啟的是詳細的feign日志,FULL表示最為詳細的,點進去有4個return Logger.Level.FULL;}//還需要在yml中配置feign日志已什么級別監控那個接口 }

PaymentOpenFeign 為OpenFeign的接口

package com.fs.feign;import com.fs.config.OpenFeignConfig; import com.fs.pojo.Payment; import com.fs.result.Result; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.RequestMapping;import java.util.List; /*** feign的聲明式接口,發起遠程調用的,簡化restTemplate** 1.定義接口* 2.接口上添加注解@FeignClient(value = "注冊中心服務提供者名",configuration=定義的OpenFeign的日志類)* 3.編寫調用接口,接口的聲明規則和提供方接口保持一致* 4.去controller注入改接口對象,調用接口方法來完成遠程調用*/ @FeignClient(value = "fs-provider-nacos",configuration = OpenFeignConfig.class) public interface PaymentOpenFeign {//復制服務提供的controller方法,路徑記得加上controller類上的路徑@RequestMapping("/payment/findAll")Result<List<Payment>> findAll();//測試time超時,由于我們在服務提供方的這個方法制作了sleep2秒,由于feign底層基于Ribbon,//Ribbon默認超時時間為1秒,所以報錯java.net.SocketTimeoutException: Read timed out//解決辦法在配置文件中配置Ribbon的超時時間@RequestMapping("/payment/testTimeOut")Result test(); }

PaymentController 使用OpenFeign遠程調用服務提供者

package com.fs.controller;import com.fs.feign.PaymentOpenFeign; import com.fs.pojo.Payment; import com.fs.result.Result; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;import java.util.List;@RestController @RequestMapping("/consumer") public class PaymentController {//注入OpenFeign接口@Autowiredprivate PaymentOpenFeign paymentOpenFeign;@RequestMapping("/payment/findAll")public Result<List<Payment>> findAll(){//調用OpenFeign接口Result<List<Payment>> all = paymentOpenFeign.findAll();return all;}//測試time超時@RequestMapping("/payment/testTimeOut")Result test(){Result test = paymentOpenFeign.test();return test;}}

測試nacos

首先確保docker的nacos正常運行且能正常訪問

運行:
FsNacosProvider8001
運行:
FsNacosConsumer80

瀏覽器訪問nacos查看服務是否注冊

直接訪問服務提供接口,與使用消費者端遠程調用服務提供接口

總結

以上是生活随笔為你收集整理的SpringCloud微服务架构,Spring Cloud 服务治理(Eureka,Consul,Nacos),Ribbon 客户端负载均衡,RestTemplate与OpenFeign实现远程调用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。