文章目錄
- SpringCloud學習筆記(1)- Spring Cloud Netflix
- 單體應用存在的問題
- Spring Cloud Eureka
- Eureka Server代碼實現
- Eureka Client 代碼實現
- RestTemplate 的使用
- 服務消費者 consumer
- 服務網關
- Ribbon 負載均衡
- Feign
- Hystrix 容錯機制
- Spring Cloud 配置中心
- Spring Cloud Config 遠程配置
- 服務跟蹤
- 創建 Zipkin Server
- 創建 Zipkin Client
SpringCloud學習筆記(1)- Spring Cloud Netflix
單體應用存在的問題
- 隨著業務的發展,開發變得越來越復雜。
- 修改、新增某個功能,需要對整個系統進行測試、重新部署。
- 一個模塊出現問題,很可能導致整個系統崩潰。
- 多個開發團隊同時對數據進行管理,容易產生安全漏洞。
- 各個模塊使用同一種技術進行開發,各個模塊很難根據實際情況選擇更合適的技術框架,局限性很大。
- 模塊內容過于復雜,如果員工離職,可能需要很長時間才能完成工作交接。
分布式、集群
集群:一臺服務器無法負荷高并發的數據訪問量,那么就設置十臺服務器一起分擔壓力,十臺不行就設置一百臺(物理層面)。很多人干同一件事情,來分攤壓力。
分布式:將一個復雜問題拆分成若干個簡單的小問題,將一個大型的項目架構拆分成若干個微服務來協同完成。(軟件設計層面)。將一個龐大的工作拆分成若干個小步驟,分別由不同的人完成這些小步驟,最終將所有的結果進行整合實現大的需求。
服務治理的核心由三部分組成:服務提供者、服務消費者、注冊中心。
在分布式系統架構中,每個微服務在啟動時,將自己的信息存儲在注冊中心,叫做服務注冊。
服務消費者從注冊中心獲取服務提供者的網絡信息,通過該信息調用服務,叫做服務發現。
Spring Cloud 的服務治理使用 Eureka 來實現,Eureka 是 Netflix 開源的基于 REST 的服務治理解決方案,Spring Cloud 集成了 Eureka,提供服務注冊和服務發現的功能,可以和基于 Spring Boot 搭建的微服務應用輕松完成整合,開箱即用,Spring Cloud Eureka。
Spring Cloud Eureka
- Eureka Server,注冊中心
- Eureka Client,所有要進行注冊的微服務通過 Eureka Client 連接到 Eureka Server,完成注冊。
Eureka Server代碼實現
<parent><groupId>org.springframework.boot
</groupId><artifactId>spring-boot-starter-parent
</artifactId><version>2.0.7.RELEASE
</version>
</parent><dependencies><dependency><groupId>org.springframework.boot
</groupId><artifactId>spring-boot-starter-web
</artifactId></dependency><dependency><groupId>javax.xml.bind
</groupId><artifactId>jaxb-api
</artifactId><version>2.3.0
</version></dependency><dependency><groupId>com.sun.xml.bind
</groupId><artifactId>jaxb-impl
</artifactId><version>2.3.0
</version></dependency><dependency><groupId>com.sun.xml.bind
</groupId><artifactId>jaxb-core
</artifactId><version>2.3.0
</version></dependency><dependency><groupId>javax.activation
</groupId><artifactId>activation
</artifactId><version>1.1.1
</version></dependency>
</dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud
</groupId><artifactId>spring-cloud-dependencies
</artifactId><version>Finchley.SR2
</version><type>pom
</type><scope>import
</scope></dependency></dependencies>
</dependencyManagement>
<dependencies><dependency><groupId>org.springframework.cloud
</groupId><artifactId>spring-cloud-starter-netflix-eureka-server
</artifactId><version>2.0.2.RELEASE
</version></dependency>
</dependencies>
- 創建配置文件 application.yml,添加 Eureka Server 相關配置。
server:port: 8761
eureka:client:register-with-eureka: falsefetch-registry: falseservice-url:defaultZone: http
://localhost
:8761/eureka/
屬性說明
server.port:當前 Eureka Server 服務端口。
eureka.client.register-with-eureka:是否將當前的 Eureka Server 服務作為客戶端進行注冊。
eureka.client.fetch-fegistry:是否獲取其他 Eureka Server 服務的數據。
eureka.client.service-url.defaultZone:注冊中心的訪問地址。
package com.southwind;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {public static void main(String[] args
) {SpringApplication.run(EurekaServerApplication.class,args
);}
}
注解說明:
@SpringBootApplication:聲明該類是 Spring Boot 服務的入口。
@EnableEurekaServer:聲明該類是一個 Eureka Server 微服務,提供服務注冊和服務發現功能,即注冊中心。
Eureka Client 代碼實現
<dependencies><dependency><groupId>org.springframework.cloud
</groupId><artifactId>spring-cloud-starter-netflix-eureka-client
</artifactId><version>2.0.2.RELEASE
</version></dependency>
</dependencies>
- 創建配置文件 application.yml,添加 Eureka Client 相關配置
server:port: 8010
spring:application:name: provider
eureka:client:service-url:defaultZone: http
://localhost
:8761/eureka/
instance:prefer-ip-address: true
屬性說明:
spring.application.name:當前服務注冊在 Eureka Server 上的名稱。
eureka.client.service-url.defaultZone:注冊中心的訪問地址。
eureka.instance.prefer-ip-address:是否將當前服務的 IP 注冊到 Eureka Server。
package com.southwind;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class ProviderApplication {public static void main(String[] args
) {SpringApplication.run(ProviderApplication.class,args
);}
}
package com.southwind.entity;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {private long id
;private String name
;private int age
;
}
package com.southwind.repository;import com.southwind.entity.Student;import java.util.Collection;public interface StudentRepository {public Collection<Student> findAll();public Student findById(long id
);public void saveOrUpdate(Student student
);public void deleteById(long id
);
}
package com.southwind.repository.impl;import com.southwind.entity.Student;
import com.southwind.repository.StudentRepository;
import org.springframework.stereotype.Repository;import java.util.Collection;
import java.util.HashMap;
import java.util.Map;@Repository
public class StudentRepositoryImpl implements StudentRepository {private static Map<Long,Student> studentMap
;static {studentMap
= new HashMap<>();studentMap
.put(1L,new Student(1L,"張三",22));studentMap
.put(2L,new Student(2L,"李四",23));studentMap
.put(3L,new Student(3L,"王五",24));}@Overridepublic Collection<Student> findAll() {return studentMap
.values();}@Overridepublic Student findById(long id
) {return studentMap
.get(id
);}@Overridepublic void saveOrUpdate(Student student
) {studentMap
.put(student
.getId(),student
);}@Overridepublic void deleteById(long id
) {studentMap
.remove(id
);}
}
package com.southwind.controller;import com.southwind.entity.Student;
import com.southwind.repository.StudentRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.util.Collection;@RestController
@RequestMapping("/student")
public class StudentHandler {@Autowiredprivate StudentRepository studentRepository
;@GetMapping("/findAll")public Collection<Student> findAll(){return studentRepository
.findAll();}@GetMapping("/findById/{id}")public Student findById(@PathVariable("id") long id
){return studentRepository
.findById(id
);}@PostMapping("/save")public void save(@RequestBody Student student
){studentRepository
.saveOrUpdate(student
);}@PutMapping("/update")public void update(@RequestBody Student student
){studentRepository
.saveOrUpdate(student
);}@DeleteMapping("/deleteById/{id}")public void deleteById(@PathVariable("id") long id
){studentRepository
.deleteById(id
);}
}
RestTemplate 的使用
RestTemplate 是 Spring 框架提供的基于 REST 的服務組件,底層是對 HTTP 請求及響應進行了封裝,提供了很多訪問 RETS 服務的方法,可以簡化代碼開發。
1、創建 Maven 工程,pom.xml。
2、創建實體類
package com.southwind.entity;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {private long id
;private String name
;private int age
;
}
3、Handler
package com.southwind.controller;import com.southwind.entity.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;import java.util.Collection;@RestController
@RequestMapping("/rest")
public class RestHandler {@Autowiredprivate RestTemplate restTemplate
;@GetMapping("/findAll")public Collection<Student> findAll(){return restTemplate
.getForEntity("http://localhost:8010/student/findAll",Collection.class).getBody();}@GetMapping("/findAll2")public Collection<Student> findAll2(){return restTemplate
.getForObject("http://localhost:8010/student/findAll",Collection.class);}@GetMapping("/findById/{id}")public Student findById(@PathVariable("id") long id
){return restTemplate
.getForEntity("http://localhost:8010/student/findById/{id}",Student.class,id
).getBody();}@GetMapping("/findById2/{id}")public Student findById2(@PathVariable("id") long id
){return restTemplate
.getForObject("http://localhost:8010/student/findById/{id}",Student.class,id
);}@PostMapping("/save")public void save(@RequestBody Student student
){restTemplate
.postForEntity("http://localhost:8010/student/save",student
,null).getBody();}@PostMapping("/save2")public void save2(@RequestBody Student student
){restTemplate
.postForObject("http://localhost:8010/student/save",student
,null);}@PutMapping("/update")public void update(@RequestBody Student student
){restTemplate
.put("http://localhost:8010/student/update",student
);}@DeleteMapping("/deleteById/{id}")public void deleteById(@PathVariable("id") long id
){restTemplate
.delete("http://localhost:8010/student/deleteById/{id}",id
);}
}
4、啟動類
package com.southwind;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;@SpringBootApplication
public class RestTemplateApplication {public static void main(String[] args
) {SpringApplication.run(RestTemplateApplication.class,args
);}@Beanpublic RestTemplate restTemplate(){return new RestTemplate();}
}
服務消費者 consumer
<dependencies><dependency><groupId>org.springframework.cloud
</groupId><artifactId>spring-cloud-starter-netflix-eureka-client
</artifactId><version>2.0.2.RELEASE
</version></dependency>
</dependencies>
server:port: 8020
spring:application:name: consumer
eureka:client:service-url:defaultZone: http
://localhost
:8761/eureka/
instance:prefer-ip-address: true
package com.southwind;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;@SpringBootApplication
public class ConsumerApplication {public static void main(String[] args
) {SpringApplication.run(ConsumerApplication.class,args
);}@Beanpublic RestTemplate restTemplate(){return new RestTemplate();}
}
package com.southwind.controller;import com.southwind.entity.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;import java.util.Collection;@RestController
@RequestMapping("/consumer")
public class ConsumerHandler {@Autowiredprivate RestTemplate restTemplate
;@GetMapping("/findAll")public Collection<Student> findAll(){return restTemplate
.getForEntity("http://localhost:8010/student/findAll",Collection.class).getBody();}@GetMapping("/findAll2")public Collection<Student> findAll2(){return restTemplate
.getForObject("http://localhost:8010/student/findAll",Collection.class);}@GetMapping("/findById/{id}")public Student findById(@PathVariable("id") long id
){return restTemplate
.getForEntity("http://localhost:8010/student/findById/{id}",Student.class,id
).getBody();}@GetMapping("/findById2/{id}")public Student findById2(@PathVariable("id") long id
){return restTemplate
.getForObject("http://localhost:8010/student/findById/{id}",Student.class,id
);}@PostMapping("/save")public void save(@RequestBody Student student
){restTemplate
.postForEntity("http://localhost:8010/student/save",student
,null).getBody();}@PostMapping("/save2")public void save2(@RequestBody Student student
){restTemplate
.postForObject("http://localhost:8010/student/save",student
,null);}@PutMapping("/update")public void update(@RequestBody Student student
){restTemplate
.put("http://localhost:8010/student/update",student
);}@DeleteMapping("/deleteById/{id}")public void deleteById(@PathVariable("id") long id
){restTemplate
.delete("http://localhost:8010/student/deleteById/{id}",id
);}
}
服務網關
Spring Cloud 集成了 Zuul 組件,實現服務網關。
Zuul 是 Netflix 提供的一個開源的 API 網關服務器,是客戶端和網站后端所有請求的中間層,對外開放一個 API,將所有請求導入統一的入口,屏蔽了服務端的具體實現邏輯,Zuul 可以實現反向代理的功能,在網關內部實現動態路由、身份認證、IP 過濾、數據監控等。
<dependencies><dependency><groupId>org.springframework.cloud
</groupId><artifactId>spring-cloud-starter-netflix-eureka-client
</artifactId><version>2.0.2.RELEASE
</version></dependency><dependency><groupId>org.springframework.cloud
</groupId><artifactId>spring-cloud-starter-netflix-zuul
</artifactId><version>2.0.2.RELEASE
</version></dependency>
</dependencies>
server:port: 8030
spring:application:name: gateway
eureka:client:service-url:defaultZone: http
://localhost
:8761/eureka/
zuul:routes:provider: /p/
**
屬性說明:
zuul.routes.provider:給服務提供者 provider 設置映射
package com.southwind;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;@EnableZuulProxy
@EnableAutoConfiguration
public class ZuulApplication {public static void main(String[] args
) {SpringApplication.run(ZuulApplication.class,args
);}
}
注解說明:
@EnableZuulProxy:包含了 @EnableZuulServer,設置該類是網關的啟動類。
@EnableAutoConfiguration:可以幫助 Spring Boot 應用將所有符合條件的 @Configuration 配置加載到當前 Spring Boot 創建并使用的 IoC 容器中。
- Zuul 自帶了負載均衡功能,修改 provider 的代碼。
package com.southwind.controller;import com.southwind.entity.Student;
import com.southwind.repository.StudentRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;import java.util.Collection;@RestController
@RequestMapping("/student")
public class StudentHandler {@Autowiredprivate StudentRepository studentRepository
;@Value("${server.port}")private String port
;@GetMapping("/findAll")public Collection<Student> findAll(){return studentRepository
.findAll();}@GetMapping("/findById/{id}")public Student findById(@PathVariable("id") long id
){return studentRepository
.findById(id
);}@PostMapping("/save")public void save(@RequestBody Student student
){studentRepository
.saveOrUpdate(student
);}@PutMapping("/update")public void update(@RequestBody Student student
){studentRepository
.saveOrUpdate(student
);}@DeleteMapping("/deleteById/{id}")public void deleteById(@PathVariable("id") long id
){studentRepository
.deleteById(id
);}@GetMapping("/index")public String index(){return "當前端口:"+this.port
;}
}
Ribbon 負載均衡
Spring Cloud Ribbon 是一個負載均衡解決方案,Ribbon 是 Netflix 發布的負載均衡器,Spring Cloud Ribbon 是基于 Netflix Ribbon 實現的,是一個用于對 HTTP 請求進行控制的負載均衡客戶端。
在注冊中心對 Ribbon 進行注冊之后,Ribbon 就可以基于某種負載均衡算法,如輪詢、隨機、加權輪詢、加權隨機等自動幫助服務消費者調用接口,開發者也可以根據具體需求自定義 Ribbon 負載均衡算法。實際開發中,Spring Cloud Ribbon 需要結合 Spring Cloud Eureka 來使用,Eureka Server 提供所有可以調用的服務提供者列表,Ribbon 基于特定的負載均衡算法從這些服務提供者中選擇要調用的具體實例。
<dependencies><dependency><groupId>org.springframework.cloud
</groupId><artifactId>spring-cloud-starter-netflix-eureka-client
</artifactId><version>2.0.2.RELEASE
</version></dependency>
</dependencies>
server:port: 8040
spring:application:name: ribbon
eureka:client:service-url:defaultZone: http
://localhost
:8761/eureka/
instance:prefer-ip-address: true
package com.southwind;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;@SpringBootApplication
public class RibbonApplication {public static void main(String[] args
) {SpringApplication.run(RibbonApplication.class,args
);}@Bean@LoadBalancedpublic RestTemplate restTemplate(){return new RestTemplate();}
}
@LoadBalanced:聲明一個基于 Ribbon 的負載均衡。
package com.southwind.controller;import com.southwind.entity.Student;
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 org.springframework.web.client.RestTemplate;import java.util.Collection;@RestController
@RequestMapping("/ribbon")
public class RibbonHandler {@Autowiredprivate RestTemplate restTemplate
;@GetMapping("/findAll")public Collection<Student> findAll(){return restTemplate
.getForObject("http://provider/student/findAll",Collection.class);}@GetMapping("/index")public String index(){return restTemplate
.getForObject("http://provider/student/index",String.class);}
}
Feign
與 Ribbon 一樣,Feign 也是由 Netflix 提供的,Feign 是一個聲明式、模版化的 Web Service 客戶端,它簡化了開發者編寫 Web 服務客戶端的操作,開發者可以通過簡單的接口和注解來調用 HTTP API,Spring Cloud Feign,它整合了 Ribbon 和 Hystrix,具有可插拔、基于注解、負載均衡、服務熔斷等一系列便捷功能。
相比較于 Ribbon + RestTemplate 的方式,Feign 大大簡化了代碼的開發,Feign 支持多種注解,包括 Feign 注解、JAX-RS 注解、Spring MVC 注解等,Spring Cloud 對 Feing 進行了優化,整合了 Ribbon 和 Eureka,從而讓 Feign 的使用更加方便。
Ribbon 是一個通用的 HTTP 客戶端工具,Feign 是基于 Ribbon 實現的。
1、Feign 是一個聲明式的 Web Service 客戶端。
2、支持 Feign 注解、Spring MVC 注解、JAX-RS 注解。
3、Feign 基于 Ribbon 實現,使用起來更加簡單。
4、Feign 集成了 Hystrix,具備服務熔斷的功能。
<dependencies><dependency><groupId>org.springframework.cloud
</groupId><artifactId>spring-cloud-starter-netflix-eureka-client
</artifactId><version>2.0.2.RELEASE
</version></dependency><dependency><groupId>org.springframework.cloud
</groupId><artifactId>spring-cloud-starter-openfeign
</artifactId><version>2.0.2.RELEASE
</version></dependency>
</dependencies>
server:port: 8050
spring:application:name: feign
eureka:client:service-url:defaultZone: http
://localhost
:8761/eureka/
instance:prefer-ip-address: true
package com.southwind;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;@SpringBootApplication
@EnableFeignClients
public class FeignApplication {public static void main(String[] args
) {SpringApplication.run(FeignApplication.class,args
);}
}
package com.southwind.feign;import com.southwind.entity.Student;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;import java.util.Collection;@FeignClient(value
= "provider")
public interface FeignProviderClient {@GetMapping("/student/findAll")public Collection<Student> findAll();@GetMapping("/student/index")public String index();
}
package com.southwind.controller;import com.southwind.entity.Student;
import com.southwind.feign.FeignProviderClient;
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.Collection;@RestController
@RequestMapping("/feign")
public class FeignHandler {@Autowiredprivate FeignProviderClient feignProviderClient
;@GetMapping("/findAll")public Collection<Student> findAll(){return feignProviderClient
.findAll();}@GetMapping("/index")public String index(){return feignProviderClient
.index();}
}
- 服務熔斷,application.yml 添加熔斷機制。
server:port: 8050
spring:application:name: feign
eureka:client:service-url:defaultZone: http
://localhost
:8761/eureka/
instance:prefer-ip-address: true
feign:hystrix:enabled: true
feign.hystrix.enabled:是否開啟熔斷器。
- 創建 FeignProviderClient 接口的實現類 FeignError,定義容錯處理邏輯,通過 @Component 注解將 FeignError 實例注入 IoC 容器中。
package com.southwind.feign.impl;import com.southwind.entity.Student;
import com.southwind.feign.FeignProviderClient;
import org.springframework.stereotype.Component;import java.util.Collection;@Component
public class FeignError implements FeignProviderClient {@Overridepublic Collection<Student> findAll() {return null;}@Overridepublic String index() {return "服務器維護中......";}
}
- 在 FeignProviderClient 定義處通過 @FeignClient 的 fallback 屬性設置映射。
package com.southwind.feign;import com.southwind.entity.Student;
import com.southwind.feign.impl.FeignError;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;import java.util.Collection;@FeignClient(value
= "provider",fallback
= FeignError.class)
public interface FeignProviderClient {@GetMapping("/student/findAll")public Collection<Student> findAll();@GetMapping("/student/index")public String index();
}
Hystrix 容錯機制
在不改變各個微服務調用關系的前提下,針對錯誤情況進行預先處理。
1、服務隔離機制
2、服務降級機制
3、熔斷機制
4、提供實時的監控和報警功能
5、提供實時的配置修改功能
Hystrix 數據監控需要結合 Spring Boot Actuator 來使用,Actuator 提供了對服務的健康健康、數據統計,可以通過 hystrix.stream 節點獲取監控的請求數據,提供了可視化的監控界面。
<dependencies><dependency><groupId>org.springframework.cloud
</groupId><artifactId>spring-cloud-starter-netflix-eureka-client
</artifactId><version>2.0.2.RELEASE
</version></dependency><dependency><groupId>org.springframework.cloud
</groupId><artifactId>spring-cloud-starter-openfeign
</artifactId><version>2.0.2.RELEASE
</version></dependency><dependency><groupId>org.springframework.boot
</groupId><artifactId>spring-boot-starter-actuator
</artifactId><version>2.0.7.RELEASE
</version></dependency><dependency><groupId>org.springframework.cloud
</groupId><artifactId>spring-cloud-starter-netflix-hystrix
</artifactId><version>2.0.2.RELEASE
</version></dependency><dependency><groupId>org.springframework.cloud
</groupId><artifactId>spring-cloud-starter-netflix-hystrix-dashboard
</artifactId><version>2.0.2.RELEASE
</version></dependency>
</dependencies>
server:port: 8060
spring:application:name: hystrix
eureka:client:service-url:defaultZone: http
://localhost
:8761/eureka/
instance:prefer-ip-address: true
feign:hystrix:enabled: true
management:endpoints:web:exposure:include: 'hystrix.stream'
package com.southwind;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
import org.springframework.cloud.openfeign.EnableFeignClients;@SpringBootApplication
@EnableFeignClients
@EnableCircuitBreaker
@EnableHystrixDashboard
public class HystrixApplication {public static void main(String[] args
) {SpringApplication.run(HystrixApplication.class,args
);}
}
注解說明:
@EnableCircuitBreaker:聲明啟用數據監控
@EnableHystrixDashboard:聲明啟用可視化數據監控
package com.southwind.controller;import com.southwind.entity.Student;
import com.southwind.feign.FeignProviderClient;
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.Collection;@RestController
@RequestMapping("/hystrix")
public class HystrixHandler {@Autowiredprivate FeignProviderClient feignProviderClient
;@GetMapping("/findAll")public Collection<Student> findAll(){return feignProviderClient
.findAll();}@GetMapping("/index")public String index(){return feignProviderClient
.index();}
}
- 啟動成功之后,訪問 http://localhost:8060/actuator/hystrix.stream 可以監控到請求數據,
- 訪問 http://localhost:8060/hystrix,可以看到可視化的監控界面,輸入要監控的地址節點即可看到該節點的可視化數據監控。
Spring Cloud 配置中心
Spring Cloud Config,通過服務端可以為多個客戶端提供配置服務。Spring Cloud Config 可以將配置文件存儲在本地,也可以將配置文件存儲在遠程 Git 倉庫,創建 Config Server,通過它管理所有的配置文件。
本地文件系統
<dependencies><dependency><groupId>org.springframework.cloud
</groupId><artifactId>spring-cloud-config-server
</artifactId><version>2.0.2.RELEASE
</version></dependency>
</dependencies>
server:port: 8762
spring:application:name: nativeconfigserver
profiles:active: native
cloud:config:server:native:search-locations: classpath
:/shared
注解說明
profiles.active:配置文件的獲取方式
cloud.config.server.native.search-locations:本地配置文件存放的路徑
- resources 路徑下創建 shared 文件夾,并在此路徑下創建 configclient-dev.yml。
server:port: 8070
foo: foo version 1
package com.southwind;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;@SpringBootApplication
@EnableConfigServer
public class NativeConfigServerApplication {public static void main(String[] args
) {SpringApplication.run(NativeConfigServerApplication.class,args
);}
}
注解說明
@EnableConfigServer:聲明配置中心。
創建客戶端讀取本地配置中心的配置文件
<dependencies><dependency><groupId>org.springframework.cloud
</groupId><artifactId>spring-cloud-starter-config
</artifactId><version>2.0.2.RELEASE
</version></dependency>
</dependencies>
- 創建 bootstrap.yml,配置讀取本地配置中心的相關信息。
spring:application:name: configclient
profiles:active: dev
cloud:config:uri: http
://localhost
:8762fail-fast: true
注解說明
cloud.config.uri:本地 Config Server 的訪問路徑
cloud.config.fail-fase:設置客戶端優先判斷 Config Server 獲取是否正常。
通過spring.application.name 結合spring.profiles.active拼接目標配置文件名,configclient-dev.yml,去 Config Server 中查找該文件。
package com.southwind;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class NativeConfigClientApplication {public static void main(String[] args
) {SpringApplication.run(NativeConfigClientApplication.class,args
);}
}
package com.southwind.controller;import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/native")
public class NativeConfigHandler {@Value("${server.port}")private String port
;@Value("${foo}")private String foo
;@GetMapping("/index")public String index(){return this.port
+"-"+this.foo
;}
}
Spring Cloud Config 遠程配置
server:port: 8070
eureka:client:serviceUrl:defaultZone: http
://localhost
:8761/eureka/
spring:application:name: configclient
- 創建 Config Server,新建 Maven 工程,pom.xml
<dependencies><dependency><groupId>org.springframework.cloud
</groupId><artifactId>spring-cloud-config-server
</artifactId><version>2.0.2.RELEASE
</version></dependency>
</dependencies>
server:port: 8888
spring:application:name: configserver
cloud:config:server:git:uri: https
://github.com/southwind9801/aispringcloud.git
searchPaths: config
username: root
password: root
label: master
eureka:client:serviceUrl:defaultZone: http
://localhost
:8761/eureka/
package com.southwind;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {public static void main(String[] args
) {SpringApplication.run(ConfigServerApplication.class,args
);}
}
創建 Config Client
<dependencies><dependency><groupId>org.springframework.cloud
</groupId><artifactId>spring-cloud-starter-config
</artifactId><version>2.0.2.RELEASE
</version></dependency><dependency><groupId>org.springframework.cloud
</groupId><artifactId>spring-cloud-starter-netflix-eureka-client
</artifactId><version>2.0.2.RELEASE
</version></dependency>
</dependencies>
spring:cloud:config:name: configclient
label: master
discovery:enabled: trueservice-id: configserver
eureka:client:service-url:defaultZone: http
://localhost
:8761/eureka/
注解說明
spring.cloud.config.name:當前服務注冊在 Eureka Server 上的名稱,與遠程倉庫的配置文件名對應。
spring.cloud.config.label:Git Repository 的分支。
spring.cloud.config.discovery.enabled:是否開啟 Config 服務發現支持。
spring.cloud.config.discovery.service-id:配置中心在 Eureka Server 上注冊的名稱。
package com.southwind;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class ConfigClientApplication {public static void main(String[] args
) {SpringApplication.run(ConfigClientApplication.class,args
);}
}
package com.southwind.controller;import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/hello")
public class HelloHandler {@Value("${server.port}")private String port
;@GetMapping("/index")public String index(){return this.port
;}
}
服務跟蹤
Spring Cloud Zipkin
Zipkin 是一個可以采集并且跟蹤分布式系統中請求數據的組件,讓開發者可以更加直觀的監控到請求在各個微服務所耗費的時間等,Zipkin:Zipkin Server、Zipkin Client。
創建 Zipkin Server
<dependencies><dependency><groupId>org.springframework.boot
</groupId><artifactId>spring-boot-starter-web
</artifactId></dependency><dependency><groupId>io.zipkin.java
</groupId><artifactId>zipkin-server
</artifactId><version>2.9.4
</version></dependency><dependency><groupId>io.zipkin.java
</groupId><artifactId>zipkin-autoconfigure-ui
</artifactId><version>2.9.4
</version></dependency>
</dependencies>
server:port: 9090
package com.southwind;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import zipkin.server.internal.EnableZipkinServer;@SpringBootApplication
@EnableZipkinServer
public class ZipkinApplication {public static void main(String[] args
) {SpringApplication.run(ZipkinApplication.class,args
);}
}
注解說明
@EnableZipkinServer:聲明啟動 Zipkin Server
創建 Zipkin Client
<dependencies><dependency><groupId>org.springframework.cloud
</groupId><artifactId>spring-cloud-starter-zipkin
</artifactId><version>2.0.2.RELEASE
</version></dependency>
</dependencies>
server:port: 8090
spring:application:name: zipkinclient
sleuth:web:client:enabled: truesampler:probability: 1.0zipkin:base-url: http
://localhost
:9090/
eureka:client:service-url:defaultZone: http
://localhost
:8761/eureka/
屬性說明
spring.sleuth.web.client.enabled:設置開啟請求跟蹤
spring.sleuth.sampler.probability:設置采樣比例,默認是 1.0
srping.zipkin.base-url:Zipkin Server 地址
package com.southwind;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class ZipkinClientApplication {public static void main(String[] args
) {SpringApplication.run(ZipkinClientApplication.class,args
);}
}
package com.southwind.controller;import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/zipkin")
public class ZipkinHandler {@Value("${server.port}")private String port
;@GetMapping("/index")public String index(){return this.port
;}
}
訪問zipkin可視化界面:http://localhost:9090/zipkin/
然后去訪問客戶端8090,即可在可視化界面看到請求記錄。
【視頻參考】https://www.bilibili.com/video/BV1p4411K7pz
【代碼參考】https://github.com/monkeyhlj/spring-study
總結
以上是生活随笔為你收集整理的SpringCloud学习笔记(1)- Spring Cloud Netflix的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。