SpringCloud基礎+基本框架
- 2019 年 12 月 27 日
- 筆記
SpringCloud極大的簡化了分散式系統的開發,實現了微服務的快速部署和靈活應用
SpringCloud主要框架
* 服務發現–Netfix Eureka
* 服務調用–Netfix Feign
* 熔斷器–Netfix Hystrix
* 服務網關–Netfix Zuul
* 分散式配置–Spring Cloud Config
* 消息匯流排–Spring Cloud Bus
注意SpringCloud和SpringBoot版本要一一對應,不然會報錯

一。Eureka服務發現

外部的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"> <modelVersion>4.0.0</modelVersion> <packaging>pom</packaging> <modules> <module>tensquare_eureka</module> </modules> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.3.RELEASE</version> </parent> <groupId>com.jinke</groupId> <artifactId>springboot</artifactId> <version>1.0-SNAPSHOT</version> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Finchley.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.0.3.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> </dependency> </dependencies> </project>
內部的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>springboot</artifactId> <groupId>com.jinke</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>tensquare_eureka</artifactId> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> <version>2.1.2.RELEASE</version> </dependency> </dependencies> </project>
application.yml
server: port: 6868 eureka: client: register-with-eureka: false fetch-registery: false service-url: defaultZone: http://127.0.0.1:${server.port}/eureka/
EurekaServer.java
package com.tensquare.eureka; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @SpringBootApplication @EnableEurekaServer public class EurekaServer { public static void main(String[] args) { SpringApplication.run(EurekaServer.class); } }
直接啟動看

二。Eureka服務註冊
新建一個module

在pom.xml中增加
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> <version>2.1.2.RELEASE</version> </dependency>
application.yml
server: port: 9004 spring: application: name: register eureka: client: service-url: defaultZone: http://127.0.0.1:6868/eureka/ instance: prefer-ip-address: true
RegisterApplication.java
package com.example.register; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; @SpringBootApplication @EnableEurekaClient public class RegisterApplication { public static void main(String[] args) { SpringApplication.run(RegisterApplication.class, args); } }
applicaiton跑起來,看結果已經註冊成功了

三。服務調用
被調register的LabelController
package com.example.register.controller; import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/label") @CrossOrigin public class LabelController { @RequestMapping(value = "/{labelId}", method = RequestMethod.GET) public String findById(@PathVariable("labelId") String id) { System.out.println("調用成功"); return "success"; } }
主調register2的ProblerController
package com.example.register2.controller; import com.example.register2.client.BaseClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @RestController @CrossOrigin @RequestMapping("/problem") public class ProblemController { @Autowired private BaseClient baseClient; @RequestMapping(value = "/label/{labelId}", method = RequestMethod.GET) public String findByLabelId(@PathVariable String labelId) { baseClient.findById(labelId); return "success"; } }
application
package com.example.register2; 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.openfeign.EnableFeignClients; @SpringBootApplication @EnableEurekaClient @EnableDiscoveryClient @EnableFeignClients public class Register2Application { public static void main(String[] args) { SpringApplication.run(Register2Application.class, args); } }
BaseClient
package com.example.register2.client; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @FeignClient("register") public interface BaseClient { @RequestMapping(value = "/label/{labelId}", method = RequestMethod.GET) public String findById(@PathVariable("labelId") String labelId); }
eureka和register、register2服務都分別跑起來

同時可以看到register的控制台輸出了「調用成功」,即代表調用其他服務成功
Spring已經實現了負載均衡,即調用服務集群時,會公平的輪流調用其中的服務
四。熔斷器
熔斷器可以有效避免雪崩現象
當被調服務掛掉以後,會走熔斷器裡面的內容
調用的服務增加實現類
package com.example.register2.client.impl; import com.example.register2.client.BaseClient; import org.springframework.stereotype.Component; @Component public class BaseClientImpl implements BaseClient { @Override public String findById(String labelId) { System.out.println("熔斷器觸發了"); return "success"; } }
application.yml增加
feign: hystrix: enabled: true
五。網關
網關的作用就相當於一個中轉分發站,介面
新建一個網關

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>springboot</artifactId> <groupId>com.jinke</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>manager</artifactId> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> <version>2.1.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</artifactId> <version>2.1.2.RELEASE</version> </dependency> </dependencies> </project>
application.yml
server: port: 9011 spring: application: name: manager eureka: client: service-url: defaultZone: http://127.0.0.1:6868/eureka/ instance: prefer-ip-address: true zuul: routes: register: path: /register/** serviceId: register
application
package com.jinke.manager; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.cloud.netflix.zuul.EnableZuulProxy; @SpringBootApplication @EnableEurekaClient @EnableZuulProxy public class ManagerApplication { public static void main(String[] args) { SpringApplication.run(ManagerApplication.class); } }
然後啟動服務即可

六。網關過濾
在網關模組新建一個過濾類即可
package com.jinke.manager.filter; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.exception.ZuulException; import org.springframework.stereotype.Component; @Component public class ManagerFilter extends ZuulFilter { @Override public String filterType() { //過濾器類型:之前或之後 return "pre"; } @Override public int filterOrder() { //多個過濾器的執行順序 return 0; } @Override public boolean shouldFilter() { //是否開啟該過濾器 return true; } @Override public Object run() throws ZuulException { //如果設置setsendzullResponse(false)表示不再繼續執行 System.out.println("已經執行到最後了"); return null; } }
七。SpringCloudConfig配置
新建config的module

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>springboot</artifactId> <groupId>com.jinke</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>config</artifactId> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-server</artifactId> <version>2.1.3.RELEASE</version> </dependency> </dependencies> </project>
application.xml
server: port: 12000 spring: application: name: config cloud: config: server: git: uri: https://gitee.com/king1039/springcloud-config.git username: [email protected] password: xxxxxx
application
package com.jinke.config; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.config.server.EnableConfigServer; @SpringBootApplication @EnableConfigServer public class ConfigApplication { public static void main(String[] args) { SpringApplication.run(ConfigApplication.class); } }
服務跑起來,如果提示Authentication is required but no CredentialsProvider has been registered是因為要帳號密碼驗證,在配置文件填上

在git上修改以後,刷新會得到新的結果
下面通過配置來調用服務
新建一個base的module

bootstrap.myl
spring: cloud: config: name: springcloud profile: config label: master uri: http://127.0.0.1:12000
git上的配置文件springcloud-config.yml
server: port: 9001 spring: application: name: base eureka: client: service-url: defaultZone: http://127.0.0.1:6868/eureka/ instance: prefer-ip-address: true
開啟eureka、config、base三個服務,然後調用

流程就是先讀取Git上的配置,然後拉下來,再調用服務
下面來通過bus消息開啟監聽
config的配置文件application.yml
server: port: 12000 spring: application: name: config cloud: config: server: git: uri: https://gitee.com/king1039/springcloud-config.git username: ********@qq.com password: ****** rabbitmq: host: ***.***.***.*** management: endpoints: web: exposure: include: bus-refresh
被調的服務配置文件
server: port: 9001 spring: application: name: base rabbitmq: host: ***.***.***.*** eureka: client: service-url: defaultZone: http://127.0.0.1:6868/eureka/ instance: prefer-ip-address: true
修改了被調配置文件後,使用post請求發送一次bus-refresh即可實現消息傳遞
如果要監聽自定義的標籤需要增加註解@RefreshScope
程式碼地址:https://github.com/king1039/SpringCloud.git
歡迎關注我的微信公眾號:Android圈