原文地址:http://blog.csdn.net/qq_18675693/article/details/53282031
本案例將打架一個微服務框架,參考來源官方參考文檔
微服務:是什么?網上有一堆資料。不做敘述。
標題提到的框架是spring-cloud-netflix相關開源框架。
demo源碼github
摘自官方說明:
Spring Cloud Netflix provides Netflix OSS integrations for Spring Boot apps through autoconfiguration and binding to the Spring Environment and other Spring programming model idioms. With a few simple annotations you can quickly enable and configure the common patterns inside your application and build large distributed systems with battle-tested Netflix components. The patterns provided include Service Discovery (Eureka), Circuit Breaker (Hystrix), Intelligent Routing (Zuul) and Client Side Load Balancing (Ribbon)..
通過上述可以了解到:
Eureka:服務發現
Hystrix:斷路器
Zuul:智能路由
Ribbon:客戶端負載均衡
先圖話后
Eureka:實際上在整個過程中維護者每個服務的生命周期。每一個服務都要被注冊到Eureka服務器上,這里被注冊到Eureka的服務又稱為Client。Eureka通過心跳來確定服務是否正常。Eureka只做請求轉發。同時Eureka是支持集群的呦!!!
Zuul:類似於網關,反向代理。為外部請求提供統一入口。
Ribbon/Feign:可以理解為調用服務的客戶端。
Hystrix:斷路器,服務調用通常是深層的,一個底層服務通常為多個上層服務提供服務,那么如果底層服務失敗則會造成大面積失敗,Hystrix就是就調用失敗后觸發定義好的處理方法,從而更友好的解決出錯。也是微服務的容錯機制。
多說不如看代碼
下面我們將搭建一個單Eureka服務器的案例,我們將會注冊兩個微服務,並配置Zuul。
目標:
1.模擬外部請求,訪問暴漏端口(Eureka監聽端口)訪問其中一個內部服務。
2.演示服務間如何通過Feign進行調用。
綜述:
我們要寫的包括:
一個Eureka服務器
兩個微服務
抽取出公共的POM部分,讓我們專注重點
<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>
<groupId>com.xbz.eureka.demo</groupId>
<artifactId>demo-eureka-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<java.version>1.7</java.version>
<file.encoding>UTF-8</file.encoding>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix</artifactId>
<version>1.2.2.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- 引入的依賴 -->
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${file.encoding}</encoding>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/libs-snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</project>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
Eureka單例服務器(即不將自身作為一個Client)
我們只需要三個步驟就可以啟動服務器
1.POM引入
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
2.搞個Main啟動類
@EnableEurekaServer
@EnableZuulProxy
package com.xbz.eureka.demo.server;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
@SpringBootApplication
@EnableEurekaServer
@EnableZuulProxy
public class EnurekaServer {
public static void main(String[] args) {
new SpringApplicationBuilder(EnurekaServer.class).web(true).run(args);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
3.重點:application.yml
#單例模式啟動Eureka Server
server:
port: 8761 #啟動端口
eureka:
client:
registerWithEureka: false #false:不作為一個客戶端注冊到注冊中心
fetchRegistry: false #為true時,可以啟動,但報異常:Cannot execute request on any known server
zuul:
prefix: /techouse #為zuul設置一個公共的前綴
#ignoredServices: '*'
routes:
cloud-client: #隨便定義,當不存在serviceId時,默認該值為serviceId(就是注冊服務的名稱,屬性spring.application.name)
path: /usersystem/** #匹配/techouse/usersystem/** 均路由到cloud-client
serviceId: cloud-client #指定路由到的serviceId
ribbon:
eureka:
enabled: false #配置zuul路由時用將此屬性設置為false
cloud-client:
ribbon:
listOfServers: 127.0.0.1:8800 #為cloud-client服務指定一組服務地址,應該是用於負載均衡
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
兩個微服務
服務cluod-client
客戶端pom
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
這個服務我們在上面的application.yml中配置了,等下我們就可以用Eureka服務器地址訪問此服務。
該服務包含一個HellController,和ServerApplication(啟動類)
HelloController.java
package com.xbz.eureka.demo.client.controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
@RestController
public class HelloController {
@RequestMapping("/hello/{fallback}")
@HystrixCommand(fallbackMethod="helloFallbackMethod")/*調用方式失敗后調用helloFallbackMethod*/
public String hello(@PathVariable("fallback") String fallback){
if("1".equals(fallback)){
throw new RuntimeException("...");
}
return "hello";
}
public String helloFallbackMethod(String fallback){
return "fallback 參數值為:"+fallback;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
ServerApplication.java
@EnableEurekaClient,確保該應用注冊到Eureka服務器
@EnableHystrix 斷路器生效
package com.xbz.eureka.demo.client;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
@SpringBootApplication
@EnableEurekaClient
@EnableHystrix
public class ServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceApplication.class, args);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
重要的application.xml
server:
port: 8800
spring:
application:
name: cloud-client #為你的應用起個名字,該名字將注冊到eureka注冊中心
eureka:
instance:
statusPageUrlPath: ${management.context-path}/info
healthCheckUrlPath: ${management.context-path}/health
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/ #去哪里注冊,eureka服務地址
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
服務cluod-client-consumer
這個服務要調用cloud-client服務中的/hello/{fallback}方法
使用@Feign(“服務名稱”),接口中隨便定義方法,然后@RequestMapping(“/hello/{fallback}”)即可,內部調用就是如此簡單。
涉及HelloService(演示如何使用@Feign)調用服務。HelloController演示調用服務的輸出結果,以及ConsumerApplication啟動類。
HelloService.java
package com.xbz.eureka.demo.consumer;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
@FeignClient("cloud-client")
public interface HelloService {
@RequestMapping("/hello/{fallback}")
public String hello(@PathVariable("fallback") String fallback);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
HelloController.java
package com.xbz.eureka.demo.consumer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@Autowired
private HelloService helloServcie;
@RequestMapping("/test/{fallback}")
public String hello(@PathVariable("fallback") String fallback){
String res=helloServcie.hello(fallback);
return "調用服務結果為"+res;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
啟動類ConsumerApplication.java
@EnableEurekaClient注冊到Eureka
@EnableFeignClients 內部使用Feign調用服務
@EnableZuulProxy 必須要有這個注解
package com.xbz.eureka.demo.consumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
@EnableFeignClients
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
重要application.xml
server:
port: 8080
spring:
application:
name: cloud-consumer #為你的應用起個名字,該名字將注冊到eureka注冊中心
eureka:
instance:
statusPageUrlPath: ${management.context-path}/info
healthCheckUrlPath: ${management.context-path}/health
client:
serviceUrl:
defaultZone: http://hadoopMaster:8761/eureka/ #去哪里注冊,eureka服務地址
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
至此,我們的服務就搭建起來了!!!
按順序啟動三個類:
EurekaServer
ServiceApplication
ConsumerApplication
正常情況下,訪問 http://127.0.0.1:8761將看到如下界面

圖中展示了我們啟動的兩個服務。
1.訪問 http://127.0.0.1:8080/test/1測試服務內部調用,且失敗會調用fallback方法返回值。
2.訪問 http://127.0.0.1:8080/test/2測試服務內部調用,則正常調用cloud-client的服務。
3.我們可以使用統一入口,調用cloud-client服務:
訪問的url: http://127.0.0.1:8761/techouse/usersystem/hello/2
以上便是一個簡單的微服務搭建嘍!!!