springcloud微服務架構搭建

SpringCloud微服務框架搭建

1、微服務架構

1.1什麼是分佈式
不一樣模塊部署在不一樣服務器上
做用:分佈式解決網站高併發帶來問題
1.2什麼是集羣
多臺服務器部署相同應用構成一個集羣
做用:經過負載均衡設備共同對外提供服務
1.3什麼是RPC
RPC 的全稱是 Remote Procedure Call 是一種進程間通訊方式。
它容許程序調用另外一個地址空間(一般是共享網絡的另外一臺機器上)的過程或函數,而不用程序員顯式編碼這個遠程調用的細節。即不管是調用本地接口/服務的仍是遠程的接口/服務,本質上編寫的調用代碼基本相同。
好比兩臺服務器A,B,一個應用部署在A服務器上,想要調用B服務器上應用提供的函數或者方法,因爲不在一個內存空間,不能直接調用,這時候須要經過就能夠應用RPC框架的實現來解決
1.3.1restful、soap、rpc
(1)RESTful是一種架構設計風格,提供了設計原則和約束條件,而不是架構。而知足這些約束條件和原則的應用程序或設計就是 RESTful架構或服務。 (2)SOAP,簡單對象訪問協議是一種數據交換協議規範, 是一種輕量的、簡單的、基於XML的協議的規範。SOAP協議和HTTP協議同樣,都是底層的通訊協議,只是請求包的格式不一樣而已,SOAP包是XML格式的。 SOAP的消息是基於xml並封裝成了符合http協議,所以,它符合任何路由器、 防火牆或代理服務器的要求。 soap可使用任何語言來完成,只要發送正確的soap請求便可,基於soap的服務能夠在任何平臺無需修改便可正常使用。 (3)RPC就是從一臺機器(客戶端)上經過參數傳遞的方式調用另外一臺機器(服務器)上的一個函數或方法(能夠統稱爲服務)並獲得返回的結果。 RPC 會隱藏底層的通信細節(不須要直接處理Socket通信或Http通信) RPC 是一個請求響應模型。客戶端發起請求,服務器返回響應(相似於Http的工做方式) RPC 在使用形式上像調用本地函數(或方法)同樣去調用遠程的函數(或方法)。 1.3.2rpc遠程調用框架 幾種比較典型的RPC的實現和調用框架。 (1)RMI實現,利用java.rmi包實現,基於Java遠程方法協議(Java Remote Method Protocol) 和java的原生序列化。 (2)Hessian,是一個輕量級的remoting onhttp工具,使用簡單的方法提供了RMI的功能。 基於HTTP協議,採用二進制編解碼。 (3)thrift是一種可伸縮的跨語言服務的軟件框架。thrift容許你定義一個描述文件,描述數據類型和服務接口。依據該文件,編譯器方便地生成RPC客戶端和服務器通訊代碼。 (4)SpringCloud 爲開發人員提供了快速構建分佈式系統的一些工具,包括配置管理、服務發現、斷路器、路由、微代理、事件總線、全局鎖、決策競選、分佈式會話等等。 
1.4什麼是SOA
業務系統分解爲多個組件,讓每一個組件都獨立提供離散,自治,可複用的服務能力
經過服務的組合和編排來實現上層的業務流程
做用:簡化維護,下降總體風險,伸縮靈活
1.5什麼是微服務
架構設計概念,各服務間隔離(分佈式也是隔離),自治(分佈式依賴總體組合)其它特性(單一職責,邊界,異步通訊,獨立部署)是分佈式概念的跟嚴格執行
 SOA到微服務架構的演進過程 做用:各服務可獨立應用,組合服務也可系統應用(巨石應用[monolith]的簡化實現策略-平臺思想) 
1.6使用RPC http技術實現會員與訂單系統通信

2、微服務架構

3、SpringCloud

SpringCloud 爲開發人員提供了快速構建分佈式系統的一些工具,包括配置管理、服務發現、斷路器、路由、微代理、事件總線、全局鎖、決策競選、分佈式會話等等。它運行環境簡單,能夠在開發人員的電腦上跑。
4、服務提供者與消費關係

服務提供者:提供服務被人調用
消費者:調用被人服務javascript

5、服務的註冊與發現(Eureka )

在這裏,咱們須要用的的組件上Spring Cloud Netflix的Eureka ,eureka是一個服務註冊和發現模塊。
4.1 服務註冊
4.1.1建立eurekaserver 項目
4.1.2引入maven依賴
以上都是概念。css


image.png
image.png

以上是個人springcloud項目,eureka是註冊中心,zuul是註冊網關,ribbon和feign都是cloud的rpc遠程調用。
zuul主要是用來配置網關java

<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.2.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <!--eureka server --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId> </dependency> <!-- spring boot test --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Dalston.RC1</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories> 

4.3配置application.yml程序員

server:
  port: 8761
eureka:
  instance:
    hostname: localhost
  client:
    registerWithEureka: false fetchRegistry: false serviceUrl: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ 

4.4啓動EurekaServerweb

@SpringBootApplication @EnableEurekaServer public class EurekaServerApplication { public static void main(String[] args) { SpringApplication.run(EurekaServerApplication.class, args); } } 

1.eureka.client.registerWithEureka=true #是否將自身註冊
2.eureka.client.fetchRegistry=false #若是爲true,啓動時報警.
4.5打開eureka server 界面的spring

image.png
image.png

4.2 服務提供者
建立一個服務提供者 (eureka client),當client向server註冊時,它會提供一些元數據,例如主機和端口,URL,主頁等。Eureka server 從每一個client實例接收心跳消息。 若是心跳超時,則一般將該實例從註冊server中刪除。

 

4.2.1 建立項目eurekaclient
4.2.2 引入maven依賴瀏覽器

<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.2.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Dalston.RC1</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories> 

4.2.3 application.yml配置bash

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/ server: port: 8762 spring: application: name: service-hi 

4.2.4 發佈服務
經過註解@EnableEurekaClient 代表本身是一個eurekaclient.服務器

@SpringBootApplication @EnableEurekaClient @RestController public class ServiceHiApplication { public static void main(String[] args) { SpringApplication.run(ServiceHiApplication.class, args); } @Value("${server.port}") String port; @RequestMapping("/hi") public String home(@RequestParam String name) { return "hi " + name + ",i am from port:" + port; } } 

4.2.5演示效果

須要指明spring.application.name,這個很重要,這在之後的服務與服務之間相互調用通常都是根據這個name 。 啓動工程,打開http://localhost:8761 ,即eureka server 的網址:restful

image.png
image.png

你會發現一個服務已經註冊在服務中了,服務名爲SERVICE-HI ,端口爲7862
這時打開  http://localhost:8762/hi?name=forezp ,你會在瀏覽器上看到 :
hi forezp,i am from port:8762

 

1、 服務消費者(Feign)

什麼是Feign
Feign是一個聲明式的僞Http客戶端,它使得寫Http客戶端變得更簡單。使用Feign,只須要建立一個接口並註解。
它具備可插拔的註解特性,可以使用Feign 註解和JAX-RS註解。Feign支持可插拔的編碼器和解碼器。
Feign默認集成了Ribbon,並和Eureka結合,默認實現了負載均衡的效果。
簡而言之:
Feign 採用的是基於接口的註解
Feign 整合了ribbon
 準備工做
繼續用上一節的工程, 啓動eureka-server,端口爲8761; 啓動service-hi 兩次,端口分別爲8762 、8773.
 準備工建立一個feign的服務
新建一個spring-boot工程,取名爲serice-feign,在它的pom文件引入Feign的起步依賴spring-cloud-starter-feign、Eureka的起步依賴
spring-cloud-starter-eureka、Web的起步依賴spring-boot-starter-web,代碼以下:
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.2.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Dalston.RC1</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories> 

application.yml配置
在工程的配置文件application.yml文件,指定程序名爲service-feign,端口號爲8765,服務註冊地址爲http://localhost:8761/eureka/ ,代碼以下:

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/ server: port: 8765 spring: application: name: service-feign 

定義一個feign接口

@FeignClient(value = "service-hi") public interface SchedualServiceHi { @RequestMapping(value = "/hi", method = RequestMethod.GET) String sayHiFromClientOne(@RequestParam(value = "name") String name); } 

一個」/hi」的API接口

@RestController public class HiController { @Autowired SchedualServiceHi schedualServiceHi; @RequestMapping(value = "/hi",method = RequestMethod.GET) public String sayHi(@RequestParam String name){ return schedualServiceHi.sayHiFromClientOne(name); } } 

啓動方式

@SpringBootApplication @EnableDiscoveryClient @EnableFeignClients public class SericeFeign { public static void main(String[] args) { SpringApplication.run(SericeFeign.class, args); } } 

演示效果

啓動程序,屢次訪問http://localhost:8765/hi?name=forezp(http://localhost:8765/hi?name=forezp),瀏覽器交替顯示: hi forezp,i am from port:8762 hi forezp,i am from port:8763 

Hystrix斷路器

在微服務架構中,根據業務來拆分紅一個個的服務,服務與服務之間能夠相互調用(RPC),在Spring Cloud能夠用RestTemplate+Ribbon和Feign來調用。爲了保證其高可用,單個服務一般會集羣部署。因爲網絡緣由或者自身的緣由,服務並不能保證100%可用,若是單個服務出現問題,調用這個服務就會出現線程阻塞,此時如有大量的請求涌入,Servlet容器的線程資源會被消耗完畢,致使服務癱瘓。服務與服務之間的依賴性,故障會傳播,會對整個微服務系統形成災難性的嚴重後果,這就是服務故障的「雪崩」效應。
爲了解決這個問題,業界提出了斷路器模型。
7.1 什麼是Hystrix
Netflix開源了Hystrix組件,實現了斷路器模式,SpringCloud對這一組件進行了整合。 在微服務架構中,一個請求須要調用多個服務是很是常見的,以下圖:


image.png
image.png

較底層的服務若是出現故障,會致使連鎖故障。當對特定的服務的調用的不可用達到一個閥值(Hystric 是5秒20次) 斷路器將會被打開。


image.png
image.png

斷路打開後,可用避免連鎖故障,fallback方法能夠直接返回一個固定值。

準備工做

這篇文章基於上一篇文章的工程,首先啓動上一篇文章的工程,啓動eureka-server 工程;啓動service-hi工程,它的端口爲8762。
在ribbon使用斷路器
改造serice-ribbon 工程的代碼,首先在pox.xml文件中加入spring-cloud-starter-hystrix的起步依賴:

<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency> 

改造service
改造HelloService類,在hiService方法上加上@HystrixCommand註解。該註解對該方法建立了熔斷器的功能,並指定了fallbackMethod熔斷方法,熔斷方法直接返回了一個字符串,字符串爲」hi,」+name+」,sorry,error!」,代碼以下:

@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!"; } } 

在啓動類上加入

@SpringBootApplication @EnableEurekaClient @EnableHystrix //斷路器 public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } @Bean @LoadBalanced RestTemplate restTemplate() { return new RestTemplate(); } } 

演示效果

image.png
相關文章
相關標籤/搜索