摘要:服務注冊中心一個服務注冊中心,所有的服務都在注冊中心注冊,負載均衡也是通過在注冊中心注冊的服務來使用一定策略來實現。在客戶端實現了負載均衡。
文章參考于史上最簡單的 SpringCloud 教程 | 終章
Spring Cloud 是一個微服務框架,與 Spring Boot 結合,開發簡單。將一個大工程項目,分成多個小 web 服務工程,可以分別獨立擴展,又可以共同合作。
環境spring 官網的 sts 3.9.2,就是有spring 相關插件的eclipse;
apache maven 3.5.4,配置阿里云鏡像
jdk1.8
Spring Cloud Finchley版本
Spring Boot 2.0.3
Spring Cloud 組件服務注冊中心、服務、斷路器、配置中心
服務的注冊與發現 - Eureka使用 Eureka 來實現服務注冊中心、服務提供者和服務消費者。
服務注冊中心一個服務注冊中心,所有的服務都在注冊中心注冊,負載均衡也是通過在注冊中心注冊的服務來使用一定策略來實現。
1.新建一個 Spring Boot 工程,用來管理服務,elipse右鍵 -> new -> Spring Starter Project :
點擊 next ,選擇 Cloud Discovery 下的 Eureka Server 組件
生成的 pom 文件:
4.0.0 com.beigege.cloud eureka-server 0.0.1-SNAPSHOT jar eureka-server spring cloud學習 org.springframework.boot spring-boot-starter-parent 2.0.3.RELEASE UTF-8 UTF-8 1.8 Finchley.RELEASE org.springframework.boot spring-boot-starter-test test org.springframework.cloud spring-cloud-starter-netflix-eureka-server org.springframework.cloud spring-cloud-dependencies ${spring-cloud.version} pom import org.springframework.boot spring-boot-maven-plugin
2.使用 @EnableEurekaServer 來說明項目是一個 Eureka:
@SpringBootApplication @EnableEurekaServer public class EurekaServerApplication { public static void main(String[] args) { SpringApplication.run(EurekaServerApplication.class, args); } }
3.修改配置文件,配置文件,可以是 application.properties 或 application.yml,這里改后綴,使用 yml,兩種格式內容都是一樣的 只是格式不同 application.yml:
server: port: 8761 #服務端口 spring: application: name: eurka-server #服務應用名稱 eureka: instance: hostname: localhost client: registerWithEureka: false #是否將自己注冊到Eureka Server,默認為true fetchRegistry: false #是否從Eureka Server獲取注冊信息,默認為true service-url: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #服務注冊的 URL
默認 eureka server 也是一個 eureka client,registerWithEureka: false 和 fetchRegistry: false 來表明項目是一個 Eureka Server。
4.運行 EurekaServerApplication 類,啟動項目,訪問項目 http://localhost:8761/
服務提供者1.新建項目名為 eureka-client 的 Spring Boot 項目,跟 Eureka Server 新建一樣,只是在選擇 Spring Boot 組件的時候,不選 Eureka Server ,選擇 Eureka Client,這里為了測試,再添加一個 Web 下的 Web 組件:
2.修改配置,application.yml:
server: port: 8762 spring: application: name: service-hi #服務之間的調用都是根據這個 name eureka: client: service-url: defaultZone: http://localhost:8761/eureka/
3.添加 @EnableEurekaClient 注解,并添加一個測試接口 /hi:
@SpringBootApplication @EnableEurekaClient @RestController public class EurekaClientApplication { public static void main(String[] args) { SpringApplication.run(EurekaClientApplication.class, args); } @Value("${server.port}") String port; @RequestMapping("/hi") public String home(@RequestParam(value = "name", defaultValue = "beigege") String name) { return "hi " + name + " ,i am from port:" + port; } }
4.啟動 Eureka Server 和 Eureka Client 項目,訪問http://localhost:8761 ,即eureka server 的網址:
服務消費者 - Ribbon | FeignSpring Cloud 兩種調用服務的方式,ribbon + restTemplate,和 feign。
Ribbonribbon 在客戶端實現了負載均衡。
啟動 Eureka Server 和 Eureka Client,修改 Eureka Client 端口,再啟動一個 Eureka Client 實例,相當于一個小的集群,訪問localhost:8761
1.新建一個 spring boot 工程,名稱為 service-ribbon,創建過程和 eureka-client 一樣,組件多選一個 Cloud Routing 下的 Ribbon,創建完成之后的 pom 文件依賴:
org.springframework.cloud spring-cloud-starter-netflix-ribbon org.springframework.cloud spring-cloud-starter-netflix-eureka-client org.springframework.boot spring-boot-starter-web org.springframework.cloud spring-cloud-starter-netflix-hystrix org.springframework.boot spring-boot-starter-test test
application.yml 配置:
server: port: 8764 spring: application: name: service-ribbon eureka: client: service-url: defaultZone: http://localhost:8761/eureka/
ServiceRibbonApplication 加上 @EnableEurekaClient 注解
2.向 Spring 注入一個 bean: restTemplate,并添加 @LoadBalanced 注解,表明這個 restTemplate 開啟負載均衡功能:
@SpringBootApplication @EnableEurekaClient public class ServiceRibbonApplication { public static void main(String[] args) { SpringApplication.run(ServiceRibbonApplication.class, args); } @Bean @LoadBalanced RestTemplate restTemplate() { return new RestTemplate(); } }
3.寫一個接口用來調用之前的 service-hi 服務的 /hi 接口:
新建 service 層,名叫 HelloService,調用 /hi 接口,這里用服務名 SERVICE-HI 代替具體的 URL:
@Service public class HelloService { @Autowired RestTemplate restTemplate; public String hiService(String name) { return restTemplate.getForObject("http://SERVICE-HI/hi?name="+name,String.class); } }
新建 controller 層,調用 service 層:
@RestController public class HelloControler { @Autowired HelloService helloService; @RequestMapping(value = "/hi") public String hi(@RequestParam String name){ return helloService.hiService(name); } }
4.啟動 service-ribbon 工程,多次訪問該工程的 /hi 接口,即 localhost:8764/hi?name=test:
hi test ,i am from port:8762
hi test ,i am from port:8763
上面交替顯示,說明實現了負載均衡,ribbon 會在客戶端發送請求時做一個負載均衡。
Feign整合了 Ribbon,具有負載均衡的能力,整合了Hystrix,具有熔斷的能力.
1.創建一個 spring boot工程,創建過程和 eureka-client 一樣,多添加一個組件 Cloud Routing 下的 Feign,項目名叫 service-feign,創建完后的 pom 文件依賴:
org.springframework.boot spring-boot-starter-web org.springframework.cloud spring-cloud-starter-netflix-eureka-client org.springframework.cloud spring-cloud-starter-openfeign org.springframework.boot spring-boot-starter-test test
application.yml 配置文件:
server: port: 8765 spring: application: name: service-feign eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/
SericeFeignApplication 上添加 @EnableEurekaClient 和 @EnableFeignClients 注解:
@SpringBootApplication @EnableEurekaClient @EnableFeignClients public class SericeFeignApplication { public static void main(String[] args) { SpringApplication.run(SericeFeignApplication.class, args); } }
2.寫一個 SchedualServiceHi 接口,通過@ FeignClient(“服務名”),來指定調用哪個服務,@GetMapping("接口名"),來向接口發送 Get 請求,@RequestParam 是請求參數:
@FeignClient(value = "service-hi") public interface SchedualServiceHi { @GetMapping("/hi") String sayHiFromClientOne(@RequestParam(value = "name") String name); }
寫一個 controller 層測試 SchedualServiceHi 接口:
@RestController public class HiController { @Autowired SchedualServiceHi schedualServiceHi; @GetMapping(value = "/hi") public String sayHi(@RequestParam String name) { return schedualServiceHi.sayHiFromClientOne( name ); } }
3.啟動 service-feign,訪問localhost:8765/hi?name=test 測試,下面交替顯示,說明實現了負載均衡:
hi test ,i am from port:8762斷路器 - Hystrix
hi test ,i am from port:8763
鏈式調用服務,其中一個服務宕機,其他服務可能會跟著異常,發生雪崩,當對一個服務的調用失敗次數到達一定閾值,斷路器會打開,執行服務調用失敗時的處理,避免連鎖故障,上面已經啟動:eureka-server、兩個 eureka-client 實例、service-ribbon 和 service-feign,下面繼續修改,分別在 service-ribbon 和 service-feign 上實現斷路器。
service-ribbon + Hystrix1.在 pom 文件中加入 Hystrix 依賴:
org.springframework.cloud spring-cloud-starter-netflix-hystrix
2.在程序的啟動類 ServiceRibbonApplication 加 @EnableHystrix 注解開啟Hystrix:
@SpringBootApplication @EnableEurekaClient @EnableHystrix public class ServiceRibbonApplication { public static void main(String[] args) { SpringApplication.run( ServiceRibbonApplication.class, args ); } @Bean @LoadBalanced RestTemplate restTemplate() { return new RestTemplate(); } }
3.添加熔斷方法,改造 HelloService 類,在 hiService 方法上面添加 @HystrixCommand 注解,fallbackMethod 是熔斷方法,當服務不可用時會執行,該方法,即 hiError 方法:
@Service public class HelloService { @Autowired RestTemplate restTemplate; @HystrixCommand(fallbackMethod = "hiError") public String hiService(String name) { return restTemplate.getForObject("http://SERVICE-HI/hi?name="+name,String.class); } public String hiError(String name) { return "hi,"+name+",sorry,error!"; } }
重啟 service-ribbon,訪問 localhost:8764/hi?name=test
hi test ,i am from port:8763
關閉兩個 eureka-client 實例,在訪問 localhost:8764/hi?name=test,瀏覽器顯示:
hi,test,sorry,error!
當服務不可用時,斷路器會迅速執行熔斷方法
service-feign + Hystrix1.Feign 自帶斷路器,在D版本的Spring Cloud之后,它沒有默認打開。需要在配置文件中配置打開:
feign: hystrix: enabled: true
2.在請求接口指定熔斷實現類,fallback 指定熔斷實現類:
@FeignClient(value ="service-hi",fallback = SchedualServiceHiHystric.class) public interface SchedualServiceHi { @GetMapping("/hi") String sayHiFromClientOne(@RequestParam(value = "name") String name); }
SchedualServiceHiHystric 類實現 SchedualServiceHi 接口:
@Component public class SchedualServiceHiHystric implements SchedualServiceHi{ @Override public String sayHiFromClientOne(String name) { return "sorry "+name; } }
3.訪問測試,重啟 service-feign,訪問 localhost:8765/hi?name=test:
sorry test
打開 eureka-client,再次訪問 localhost:8765/hi?name=test:
hi test ,i am from port:8762
證明斷路器起到作用,注意瀏覽器緩存。
路由網關 - Zuul1.創建一個 spring boot 工程,名稱為 service-zuul,創建過程和 eureka-client 一樣,組件要多添加一個 Cloud Routing 下的 Zuul,pom 文件的依賴如下:
org.springframework.cloud spring-cloud-starter-netflix-eureka-client org.springframework.boot spring-boot-starter-web org.springframework.cloud spring-cloud-starter-netflix-zuul org.springframework.boot spring-boot-starter-test test
2.在入口 application 中添加 @EnableZuulProxy 注解,開啟路由:
@SpringBootApplication @EnableEurekaClient @EnableZuulProxy public class ServiceZuulApplication { public static void main(String[] args) { SpringApplication.run(ServiceZuulApplication.class, args); } }
application.yml 配置:
server: port: 8769 spring: application: name: service-zuul eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/添加路由
修改 application.yml 添加路由配置:
server: port: 8769 spring: application: name: service-zuul eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/ zuul: routes: api-a: path: /api-a/** service-id: service-ribbon api-b: path: /api-b/** service-id: service-feign
8769 端口的所有 api-a 請求會轉發到 service-ribbon 工程,api-b 到 service-feign
啟動 service-zuul,訪問 localhost:8769/api-a/hi?name=test,瀏覽器顯示:
hi test ,i am from port:8762
訪問 localhost:8769/api-b/hi?name=test,瀏覽器顯示:
hi test ,i am from port:8762
說明路由成功。
過濾器新建自定義過濾器,繼承 ZuulFilter:
@Component public class MyFilter extends ZuulFilter { private static Logger log = LoggerFactory.getLogger(MyFilter.class); /* * filterType:返回一個字符串代表過濾器的類型,在zuul中定義了四種不同生命周期的過濾器類型,具體如下: * pre:路由之前 * routing:路由之時 * post: 路由之后 * error:發送錯誤調用 */ @Override public String filterType() { return "pre"; } /* * filterOrder:過濾的順序 */ @Override public int filterOrder() { return 0; } /* * shouldFilter:這里可以寫邏輯判斷,是否要過濾,本文true,永遠過濾。 */ @Override public boolean shouldFilter() { return true; } /* * run:過濾器的具體邏輯。可以很復雜,包括查sql,nosql去判斷該請求到底有沒有權限訪問, * 這里是判斷請求有沒有 token 參數 */ @Override public Object run() { RequestContext ctx = RequestContext.getCurrentContext(); HttpServletRequest request = ctx.getRequest(); log.info(String.format("%s >>> %s", request.getMethod(), request.getRequestURL().toString())); Object accessToken = request.getParameter("token"); if(accessToken == null) { log.warn("token is empty"); ctx.setSendZuulResponse(false); ctx.setResponseStatusCode(401); try { ctx.getResponse().getWriter().write("token is empty"); }catch (Exception e){} return null; } log.info("ok"); return null; } }
重啟 service-zuul 訪問 localhost:8769/api-a/hi?name=test,瀏覽器顯示
token is empty
加上 token 參數:localhost:8769/api-a/hi?name=test&token=666
hi test ,i am from port:8762分布式配置中心 遠程資源庫
1.這里在 碼云 注冊一個賬號,用來創建存儲配置的資源庫,在碼云上創建一個名叫 SpringCloudConfig 項目:
2.新建一個配置文件 config-client-dev.properties,也可以是 yml 配置文件,內容為 test = version 1,然后提交:
2.默認是 master 分支,新建一個分支,名字叫 aa:
修改 aa 分支中的 config-client-dev.properties 配置文件的 test 屬性為 version 2:
config-server1.新建 spring boot 項目,組件選擇 Cloud Config 中的 Config Server,pom 中的依賴:
org.springframework.cloud spring-cloud-config-server org.springframework.boot spring-boot-starter-test test
在入口程序添加 @EnableConfigServer 注解:
@SpringBootApplication @EnableConfigServer public class ConfigServerApplication { public static void main(String[] args) { SpringApplication.run(ConfigServerApplication.class, args); } }
application.yml 配置文件,如果是公開的不需要填寫用戶名密碼:
server: port: 8888 spring: application: name: config-server cloud: config: server: git: uri: https://gitee.com/candy-boy/SpringCloudConfig #配置git倉庫地址,后面的.git可有可無 username: #訪問git倉庫的用戶名,碼云登陸用戶名 password: #訪問git倉庫的用戶密碼,碼云登陸密碼
2.訪問測試,啟動程序,訪問配置文件,可以如下訪問:
{application}/{profile}[/{label}]
如 localhost:8888/config-client/dev,即訪問 config-client-dev.properties,其中 {application} 就是 最后一道橫線前面的 config-client,{profile} 是最后一道橫線后面到點,即 dev,{label} 指的是資源庫的分支,不填則為默認分支,剛創建的資源庫,默認分支是 master,訪問結果如下:
其他訪問方式如:
/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
如果是下面這樣,可能是用戶名或密碼錯誤:
3.測試其他分支,訪問 aa 分支下的 config-client-dev.properties,localhost:8888/config-client/dev/aa
config-client待續....
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/76532.html
摘要:快速入門這個快速入門使用的服務器和客戶端。屬性在端點中顯示為高優先級屬性源,如以下示例所示。名為的屬性源包含值為且具有最高優先級的屬性。屬性源名稱中的是存儲庫,而不是配置服務器。 Spring Cloud Config快速入門 這個快速入門使用Spring Cloud Config Server的服務器和客戶端。 首先,啟動服務器,如下所示: $ cd spring-cloud-con...
摘要:介紹隨著微服務的流行,服務和服務之間的穩定性變得越來越重要。以流量為切入點,從流量控制熔斷降級系統負載保護等多個維度保護服務的穩定性。完備的實時監控同時提供實時的監控功能。您只需要引入相應的依賴并進行簡單的配置即可快速地接入。 Sentinel 介紹 隨著微服務的流行,服務和服務之間的穩定性變得越來越重要。 Sentinel 以流量為切入點,從流量控制、熔斷降級、系統負載保護等多個維度...
摘要:它通過使用來連接消息代理中間件以實現消息事件驅動的微服務應用。該示例主要目標是構建一個基于的微服務應用,這個微服務應用將通過使用消息中間件來接收消息并將消息打印到日志中。下面我們通過編寫生產消息的單元測試用例來完善我們的入門內容。 之前在寫Spring Boot基礎教程的時候寫過一篇《Spring Boot中使用RabbitMQ》。在該文中,我們通過簡單的配置和注解就能實現向Rabbi...
摘要:基礎知識官網傳送門項目結構文件文件代表工程對象模型它是使用工作的基本組件,位于工程根目錄。表示被依賴的僅參與測試相關的處理,包裹測試代碼的編譯,執行。 Maven 基礎知識 官網: 傳送門 Maven 項目結構 $ MavenProject |-- pom.xml |-- src | |-- main | | `-- java | | `-- resources |...
閱讀 2395·2021-11-11 16:54
閱讀 1204·2021-09-22 15:23
閱讀 3644·2021-09-07 09:59
閱讀 1990·2021-09-02 15:41
閱讀 3283·2021-08-17 10:13
閱讀 3037·2019-08-30 15:53
閱讀 1235·2019-08-30 13:57
閱讀 1210·2019-08-29 15:16