<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          從零搭建 Spring Cloud 服務(wù)(超級詳細)

          共 9231字,需瀏覽 19分鐘

           ·

          2020-11-11 02:40

          點擊上方藍色“小哈學(xué)Java”,選擇“設(shè)為星標

          回復(fù)“資源”獲取獨家整理的學(xué)習(xí)資料!

          來源:blog.csdn.net/qq_29519041/article/details/85238270


          這里會介紹很多基礎(chǔ)知識,直接想開始搭建微服務(wù)的可以看第二章,微服務(wù)的搭建。直接看第二章不會有什么影響,可以先學(xué)會開車再學(xué)習(xí)車的構(gòu)造的,看個人習(xí)慣來。

          1.什么是SpringCloud?

          SpringCloud官網(wǎng):https://spring.io/projects/spring-cloud(個人建議是用谷歌瀏覽器訪問官網(wǎng)打開中文翻譯粗略把官網(wǎng)讀一遍)

          個人理解:

          以前的服務(wù)器就好像,一個會語數(shù)外全能的老師,為學(xué)生提供服務(wù),這個老師生病了,那全校停課?,F(xiàn)在微服務(wù)流行后,學(xué)校有了數(shù)學(xué)教研組,語文教研組,外語教研組,每個教研組有一群老師具體負責(zé)某科的教學(xué),缺了誰,學(xué)校都照樣運轉(zhuǎn)。

          而這個變化中,那些改變歷史的程序員就是把一個服務(wù)器中的眾多服務(wù),或好幾臺服務(wù)器中的眾多服務(wù),分類出來,解耦合出來,把他們類似的功能交給同一個集群來做,把互相耦合在一起的功能剝離出來,按業(yè)務(wù),按功能來把他們作為一個個微服務(wù)放在服務(wù)器上,而這個服務(wù)器就只提供一個服務(wù),或較少的服務(wù)。

          讓一個超大的服務(wù)邏輯,解耦合為一個個小服務(wù),均勻的分布在各自的服務(wù)器中。微服務(wù)就微在這。每個教研組就是一個微服務(wù)集群。他們提供同樣的服務(wù),而注冊中心Eureka就是這個存放這個教研組老師名單的地方,學(xué)生們想先訪問這個注冊中心獲取教師名單,然后根據(jù)相應(yīng)的負載方法去訪問各自老師。不至于讓集群中某一老師累死也不至于讓某一老師閑死。

          Zuul網(wǎng)關(guān)呢,就是學(xué)校的門衛(wèi),某些學(xué)生來學(xué)校找誰,它負責(zé)指引(路由),并且通過一些非常簡單的配置,達到阻攔一些人進入(身份驗證),或者控制想學(xué)數(shù)學(xué)的人只能去數(shù)學(xué)教研組,不能去核能教研組學(xué)怎么造原子彈(權(quán)限驗證)。

          Hystrix熔斷器呢,可以把它當成學(xué)校的志愿者,當一個教研組集體罷課后,學(xué)生找不到老師了,這些志愿者及時的告訴來訪問的學(xué)生,相應(yīng)的結(jié)果,異常信息等,免得大量的學(xué)生在學(xué)校等待,這些志愿者趕快把這些等待的學(xué)生梳理出去,學(xué)生一直在學(xué)校等待,那其他需要學(xué)生的學(xué)校,也會等待學(xué)生,最后造成大面積的學(xué)校癱瘓。這里學(xué)生我們看成一個個請求。熔斷器就是把某事故的蔓延即使熔斷了。

          當然這些組件也是微服務(wù)需要注冊到Eureka注冊中心

          Spring Cloud 就可以看成是這個學(xué)校了。眾多上面提到的組件相當于都是這個學(xué)校的各職能部門。

          ps: 博主基于Maven+idea搭建。另外SpringCloud需要基于springboot搭建。

          2.1 引入Spring Boot相關(guān)依賴 這里的springboot用的是1.5.7版本

          引入Spring Cloud相關(guān)依賴 這里為 Edgware.SR5

          2.1 工程初始化配置

          在Idea中創(chuàng)建工程:File -> New ->Project

          點擊 ?Empty Project -> Next

          項目命名 -> 項目位置

          選擇模組 modules ->next

          進入新的窗口后,開始配置Maven,打開設(shè)置 setting

          因為我之前做過配置,因此只需要改變框1的路徑,如第一次配置需要自己找到你maven放置的位置,以及settings.xml****,repository的位置,實在不會的百度 maven集成idea

          3個框選擇完畢后點擊 ok

          接下來新建module

          這里可能會出現(xiàn)加載不出archetype list的問題

          用了網(wǎng)上的所有解決辦法花了3個小時解決都沒用,重啟之后竟然可以了····你敢信?????小時候網(wǎng)吧網(wǎng)管的至理名言都忘了?。≈貑⒁幌侣铮?!

          出來之后 選擇quickstart ->下一步

          名字自己想 想好后,復(fù)制一下你想好的 ArtifactId點擊Next,groupId為組織名 也是自己想一個,一般為公司網(wǎng)址反寫。

          粘貼后下一步

          提供注冊服務(wù)的服務(wù)器pom.xml配置如下:



          <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.0modelVersion>

          ??<groupId>com.yungroupId>
          ??<artifactId>springcloud-eureka-serverartifactId>
          ??<version>1.0-SNAPSHOTversion>

          ??<name>springcloud-eureka-servername>
          ??
          ??<url>http://www.example.comurl>

          ??<properties>
          ????<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
          ????<maven.compiler.source>1.7maven.compiler.source>
          ????<maven.compiler.target>1.7maven.compiler.target>
          ??properties>

          ??
          ??<parent>
          ????<groupId>org.springframework.bootgroupId>
          ????<artifactId>spring-boot-starter-parentartifactId>
          ????<version>1.5.7.RELEASEversion>
          ??parent>

          ??<dependencies>
          ????
          ????<dependency>
          ??????<groupId>org.springframework.cloudgroupId>
          ??????<artifactId>spring-cloud-starter-netflix-eureka-serverartifactId>
          ????dependency>

          ??dependencies>


          ??
          ??<dependencyManagement>
          ????<dependencies>
          ??????<dependency>
          ????????<groupId>org.springframework.cloudgroupId>
          ????????<artifactId>spring-cloud-dependenciesartifactId>
          ????????<version>Edgware.SR5version>
          ????????<type>pomtype>
          ????????<scope>importscope>
          ??????dependency>
          ????dependencies>
          ??dependencyManagement>
          project>

          點擊Import Changes

          等待右下角加載springcloud的依賴

          2.2 Springboot的搭建 以及提供注冊服務(wù) 的 服務(wù)配置

          創(chuàng)建resources文件夾

          并設(shè)置作為資源根目錄,之后文件變成這樣

          之后文件夾變成有黃色的橫杠

          在resources下新建文件,文件名為application.yml ?(對是yml 不是xml ,博主第一次學(xué)習(xí)時,還以為是其他博主打錯了,踩了一個小坑)

          配置yml,注意:如果只配置前兩行端口號信息會報錯

          server:
          ??port:?8700?#?端口自己決定

          #?指定當前eureka客戶端的注冊地址,也就是eureka服務(wù)的提供方,當前配置的服務(wù)的注冊服務(wù)方
          eureka:
          ??client:
          ????service-url:
          ??????defaultZone:?http://${eureka.instance.hostname}:${server.port}/eureka
          ????register-with-eureka:?false?#自身?不在向eureka注冊
          ????fetch-registry:?false?#啟動時禁用client的注冊
          ??instance:
          ????hostname:?localhost

          #指定應(yīng)用名稱
          spring:
          ??application:
          ????name:?eureka-server

          知識補充:

          開發(fā) spring boot 的入口類 EurekaServerApplication.java

          EurekaServerApplication.java

          package?com.yun;

          import?org.springframework.boot.SpringApplication;
          import?org.springframework.boot.autoconfigure.SpringBootApplication;
          import?org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

          @SpringBootApplication
          @EnableEurekaServer?//當前使用eureka的server
          public?class?EurekaServerApplication?{
          ????public?static?void?main(String[]?args)?{
          ????????SpringApplication.run(EurekaServerApplication.class,args);
          ????}
          }

          右鍵運行當前類:

          運行成功console畫面

          嘗試進入eureka管理界面 端口號為 yml里配置的(端口號自己設(shè)置 需要大于公用和保留的端口號)1024~65535

          一般我喜歡設(shè)置為 8700到8800之間

          如下 管理界面已經(jīng)可以登錄了

          2.3 客戶端client 提供真正服務(wù)的角色的配置, 它提供服務(wù) 在 服務(wù)注冊方server (注冊中心)進行注冊

          同樣新建module,選擇quickstart點擊下一步

          兩個位置 置空

          取名 下一步

          注意這里要在根目錄springcloud 下創(chuàng)建模組,content root 會默認在之前的模組之下創(chuàng)建模組 這樣創(chuàng)建模組會出現(xiàn)問題并報錯

          推薦這種配置方法 在content root下springcloud后改名字 ?如下圖配置點下一步,紅框處一般默認為上一個模組的文件目錄名,需要改為你的模組名

          成功后為并列狀態(tài),如不為并列或報錯請重新配置

          配置servicesupport的pom,與server的pom配置相同,只需要把第一個pom的1的方框處server改為client

          和第一個微服務(wù)同理 我們需要配置入口類 pom.xml application.yml,因為是服務(wù)提供者,這里還需編寫服務(wù)類controller

          application.yml

          server:
          ??port:?8701?#?服務(wù)提供方

          #?指定當前eureka客戶端的注冊地址,
          eureka:
          ??client:
          ????service-url:
          ??????defaultZone:?http://${eureka.instance.hostname}:8700/eureka
          ??instance:
          ????hostname:?localhost

          #當前服務(wù)名稱
          spring:
          ??application:
          ????name:?eureka-service

          pom.xml:

          編寫所提供的 服務(wù)controller

          @RestController
          @RequestMapping("/Hello")
          public?class?Controller?{
          ????@RequestMapping("/World")
          ????public?String?helloWorld(String?s){
          ????????System.out.println("傳入的值為:"+s);
          ????????return?"傳入的值為:"+s;
          ????}
          }

          入口類 并運行此微服務(wù):

          @SpringBootApplication
          @EnableDiscoveryClient//代表自己是一個服務(wù)提供方
          public?class?EurekaServiceApplication?{
          ????public?static?void?main(String[]?args)?{
          ????????SpringApplication.run(EurekaServiceApplication.class,args);
          ????}
          }

          右鍵入口類名點擊 run(當然開啟此服務(wù)時需要先開啟server服務(wù) 就是我們第一個編寫的微服務(wù))

          此時再進入服務(wù)注冊的頁面 http://localhost:8700/

          可以看見服務(wù)提供者已被注冊進 服務(wù)注冊者

          在直接訪問一下服務(wù)提供者的 網(wǎng)絡(luò)位置http://localhost:8701/Hello/World?s=小沛

          我們已經(jīng)看見 可以訪問了,證明此微服務(wù)可用。

          但是我們一般不直接調(diào)用所需的微服務(wù),而是經(jīng)過提供注冊服務(wù)服務(wù)器server,獲取所需的服務(wù)提供者列表(為一個列表,此列表包含了能提供相應(yīng)服務(wù)的服務(wù)器),他們也許是個集群,因此server會返回一個 ip+端口號的表,服務(wù)消費者通過相應(yīng)算法訪問這表上的不同服務(wù)器,這些服務(wù)器提供的是相同的服務(wù),這種在服務(wù)消費者一方挑選服務(wù)器為自己服務(wù)的方式是一種客戶端的負載均衡。

          目前博主所知的有 輪詢隨機兩種方式 訪問這些服務(wù)器,輪詢就是循環(huán)的意思,假如有3臺服務(wù)器,訪問方式就是1,2,3,1,2,3,1,2,3····,隨機就是隨機,回想一下random方法,一種無規(guī)律的方式。這兩種方式都是為了,訪問每個服務(wù)器的可能性盡量的相同。還有權(quán)重負載這種算法,意思就是 根據(jù)服務(wù)器負載能力的分配相應(yīng)的服務(wù)。能力大的干得多。能力小的干得少。

          2.4 服務(wù)的調(diào)用方式

          第一種調(diào)用方式:restTemplate+ribbon

          第二種調(diào)用方式:feign

          2.4.1 restTemplate+ribbon

          ribbon是一種負載均衡的客戶端,它是什么呢?請詳讀https://www.jianshu.com/p/1bd66db5dc46

          可以看見其中的一段如下:

          客戶端負載均衡服務(wù)端負載均衡最大的不同點在于上面所提到服務(wù)清單所存儲的位置。在客戶端負載均衡中,所有客戶端節(jié)點都維護著自己要訪問的服務(wù)端清單,而這些服務(wù)端端清單來自于服務(wù)注冊中心,比如上一章我們介紹的Eureka服務(wù)端。

          同服務(wù)端負載均衡的架構(gòu)類似,在客戶端負載均衡中也需要心跳去維護服務(wù)端清單的健康性,默認會創(chuàng)建針對各個服務(wù)治理框架的Ribbon自動化整合配置,比如Eureka中的org.springframework.cloud.netflix.ribbon.eureka.RibbonEurekaAutoConfiguration,Consul中的org.springframework.cloud.consul.discovery.RibbonConsulAutoConfiguration。在實際使用的時候,我們可以通過查看這兩個類的實現(xiàn),以找到它們的配置詳情來幫助我們更好地使用它。

          接下來我們來搭建基于ribbon的客戶端,他用于消費服務(wù)。

          同理先搭建springboot的環(huán)境

          與之前搭建servicesupport不同的是:

          第一步:現(xiàn)在pom中需要在dependencies中添加ribbon依賴

          <dependency>
          ???????<groupId>org.springframework.cloudgroupId>
          ???????<artifactId>spring-cloud-starter-ribbonartifactId>
          dependency>

          第二步:yml如下配置:

          server:
          ??port:?8702?#?服務(wù)消費方

          #?指定當前eureka客戶端的注冊地址,
          eureka:
          ??client:
          ????service-url:
          ??????defaultZone:?http://${eureka.instance.hostname}:8700/eureka
          ??instance:
          ????hostname:?localhost

          #當前服務(wù)名稱
          spring:
          ??application:
          ????name:?eureka-consumer

          服務(wù)的消費方依舊需要在注冊方8700端口去注冊。配置當前服務(wù)消費方的端口8072,名字為eureka-consumer

          第三步:依舊需要啟動類,因為它是一個springboot的架構(gòu):

          @SpringBootApplication
          @EnableDiscoveryClient?//當前使用eureka的server
          public?class?EurekaConsumerApplication?{
          ????public?static?void?main(String[]?args)?{
          ????????SpringApplication.run(EurekaConsumerApplication.class,args);
          ????}
          }

          如上圖:

          我們需要一個controller類來編寫ribbon的代碼。

          @RestController
          @RequestMapping("/Hello")
          class?ConsumerController?{
          ????@Autowired
          ????private?LoadBalancerClient?loadBalancerClient;
          ????@Autowired
          ????private?RestTemplate?restTemplate;
          ????@RequestMapping("/Consumer")
          ????public?String?helloWorld(String?s){
          ????????System.out.println("傳入的值為:"+s);
          ????????//第一種調(diào)用方式
          ????????//String?forObject?=?new?RestTemplate().getForObject("http://localhost:8071/Hello/World?s="?+?s,?String.class);

          ????????//第二種調(diào)用方式
          ????????//根據(jù)服務(wù)名?獲取服務(wù)列表?根據(jù)算法選取某個服務(wù)?并訪問某個服務(wù)的網(wǎng)絡(luò)位置。
          ????????//ServiceInstance?serviceInstance?=?loadBalancerClient.choose("EUREKA-SERVICE");
          ????????//String?forObject?=?new?RestTemplate().getForObject("http://"+serviceInstance.getHost()+":"+serviceInstance.getPort()+"/Hello/World?s="+s,String.class);

          ????????//第三種調(diào)用方式?需要restTemplate注入的方式
          ????????String?forObject?=?restTemplate.getForObject("http://EUREKA-SERVICE/Hello/World?s="?+?s,?String.class);
          ????????return?forObject;
          ????}
          }

          我們常用第三種調(diào)用方式。

          第一種是直接調(diào)用:不經(jīng)過注冊中心那服務(wù)列表,直接訪問的servicesupport

          第二種:是根據(jù)服務(wù)名選擇調(diào)用,如上圖需要做如下注入

          @Autowired private LoadBalancerClient loadBalancerClient;

          如上圖代碼中第二種調(diào)用方法的代碼所示。

          用服務(wù)名去注冊中心獲取服務(wù)列表,當前客戶端底層會做隨機算法的選取獲得服務(wù)并訪問。

          第三種需要一個@Bean的注解自動注入并直接調(diào)用restTemplate對象調(diào)用服務(wù)。底層調(diào)用模式與第二種調(diào)用方式一樣。如下:

          @Configuration
          public?class?Beans?{
          ????//管理簡單對象
          ????@Bean
          ????@LoadBalanced
          ????public?RestTemplate?getRestTemplate(){
          ????????return?new?RestTemplate();
          ????}
          }

          @Bean注解告訴工廠,這個方法需要自動注入。

          @LoadBalanced,表示需要做負載勻衡。

          然后如controller中一樣注入一下restTemplate,并且使用他,區(qū)別是可以直接使用服務(wù)名訪問了

          String forObject =

          restTemplate.getForObject("http://EUREKA-SERVICE/Hello/World?s=" + s, String.class);

          開始測試:

          1.運行server的啟動類:

          2.運行servicesupport的啟動類:

          3.運行serviceconsume的啟動類:

          瀏覽器訪問:

          8072為服務(wù)消費方的端口

          訪問方法解析:

          • 訪問服務(wù)消費方@RequestMapping指定的路徑及消費方的端口來訪問消費方的controller
          • controller根據(jù)服務(wù)名去server方獲取獲取服務(wù)列表,獲取服務(wù)列表后根據(jù)隨機的模式負載勻衡后去選擇服務(wù)地址去訪問servicesupport:如下圖

          2.5 ?Eureka server的高可用配置

          點擊下圖配置

          接下來配置三臺01,02,03的虛擬機參數(shù)

          01:8699

          02:8698

          03:8697

          之后點ok保存,可看見多出三個啟動項

          接下來分別改注冊端口號,defaultZone分別啟動三個啟動項

          打開server的yml配置,刪掉前兩行端口號配置(圖中有錯,請把instance 和hostname那兩行刪掉)

          配置好yml后點擊啟動

          同理,我們再次改動端口號為8699和8697后,把啟動項改為02,之后啟動(圖中有錯,請把instance 和hostname那兩行刪掉)

          同理把yml端口改為8699 和 8698后,把啟動項改為03,之后啟動(圖中有錯,請把instance 和hostname那兩行刪掉)

          啟動后分別訪問三個01,02,03端口,已經(jīng)可以看見可以訪問了。

          打開服務(wù)提供方的yml配置如下,把端口號改為三個中其中的一個。

          啟動服務(wù)提供方之后,再次訪問三個01,02,03我們會發(fā)現(xiàn)

          重點:即使服務(wù)提供方只注冊了一個端口號8699,但是另外兩個端口號,也能感知到服務(wù)提供方8701的存在了。如下圖:

          接下來像服務(wù)消費方中添加服務(wù)注冊者的端口號,這樣在server掛掉任何一個的時候,都能有其他的server也能獲取服務(wù)列表

          訪問以下服務(wù)消費方,發(fā)現(xiàn)可以通過消費方調(diào)用server服務(wù)列表并且訪問service了

          我么隨便關(guān)閉其中兩個server的副本,重啟serviceconsume,再進行訪問。必須重啟serviceconsume才能清空緩存,清掉consume里面有的服務(wù)列表。

          上圖發(fā)現(xiàn)即使關(guān)閉兩臺server后依舊可以訪問,如下圖,依舊從server中獲取了服務(wù)列表,從中也能看見之后不用再獲取服務(wù)列表了。

          但是當我們關(guān)掉所有server后。訪問還是沒問題,因為緩存了服務(wù)列表。

          但是讓我們來重啟一下serviceconsume,再訪問就不行了。

          綜上我們就完成了springcloud中server的高可用配置

          END


          有熱門推薦?

          1.?一份 Spring Boot 項目搭建模板 ~

          2.?如何設(shè)計日志采集系統(tǒng)?不妨看看這篇文章

          3.?實戰(zhàn)篇:一個核心系統(tǒng) 3 萬多行代碼的重構(gòu)之旅

          4.?IntelliJ IDEA 超全優(yōu)化設(shè)置,效率杠杠的!

          最近面試BAT,整理一份面試資料Java面試BATJ通關(guān)手冊,覆蓋了Java核心技術(shù)、JVM、Java并發(fā)、SSM、微服務(wù)、數(shù)據(jù)庫、數(shù)據(jù)結(jié)構(gòu)等等。

          獲取方式:點“在看”,關(guān)注公眾號并回復(fù)?Java?領(lǐng)取,更多內(nèi)容陸續(xù)奉上。

          文章有幫助的話,在看,轉(zhuǎn)發(fā)吧。

          謝謝支持喲 (*^__^*)

          瀏覽 54
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  成人爽爽 | 精品人妻系列 | 天天爽夜夜爽 | 香蕉网一级 | 激情五月色情在线播放 |