springcloud微服務實戰:Eureka+Zuul+Ribbon+Hystrix+SpringConfig
相信如今已經有不少小夥伴已經或者準備使用springcloud微服務了,接下來爲你們搭建一個微服務框架,後期能夠本身進行擴展。會提供一個小案例: 服務提供者和服務消費者 ,消費者會調用提供者的服務,新建的項目都是用springboot,附源碼下載。css
coding倉庫地址: coding地址 csdn下載地址: csdn下載地址html
若是有問題請在下邊評論,或者200909980加羣交流。java
Eureka:服務發現
Hystrix:斷路器
Zuul:智能路由
Ribbon:客戶端負載均衡
Turbine:集羣監控
Springcloud-config:遠程獲取配置文件mysql

接下來,咱們開始搭建項目,首先咱們到spring爲咱們提供的一個網站快速搭建springboot項目,點擊訪問,我這裏用的是gradle,若是各位客官喜歡用maven,好吧你能夠到http://mvnrepository.com/查看對應的依賴,點我訪問。nginx
1、搭建eureka-server服務springcloud-eureka-server
eureka-server做爲服務發現的核心,第一個搭建,後面的服務都要註冊到eureka-server上,意思是告訴eureka-server本身的服務地址是啥。固然還能夠用zookeeper或者springconsul。git

若是是maven項目請對應的修改pom.xmlweb
maven { url
"http://maven.aliyun.com/nexus/content/groups/public/" }
compile
group:
'org.springframework.cloud', name:
'spring-cloud-starter-eureka-server', version:
'1.3.4.RELEASE'
compile
group:
'org.springframework.boot', name:
'spring-boot-starter-security', version:
'1.5.6.RELEASE'
還有幾點須要修改的,你們對應圖片看看,就是springboot打包的時候會提示找不到主累。
redis
- 2.修改 application.yml,建議用yml。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
server:
port:
8761
eureka:
datacenter: trmap
environment: product
client:
healthcheck:
enabled:
true
service-url:
defaultZone: http:
register-with-eureka:
false #關閉本身做爲客戶端註冊
fetch-registry:
false
security:
basic:
enabled:
true
user:
name: root
#用戶名和密碼,等會訪問的時候,會要求你登陸,服務註冊的時候也須要帶着用戶名和密碼
password: booszy
- 3.修改程序的主類,建議修改類名,要加如eureka的 @EnableEurekaServer 註解,而後運行main方法。
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}

http://localhost:8761/ 這個是eureka-server的頁面地址,到這裏,說明eureka-server搭建好了,簡單吧,這一步必定要成功,不然後面的就不能繼續進行下去了,後邊基本相似。spring
2、搭建config-server服務springcloud-config-server
springcloud-config-server是用來將遠程git倉庫的配置文件動態拉下來,這樣配置文件就能夠動態的維護了。
新建一個springboot項目,修改maven私服地址,並加入一下依賴。
compile
group:
'org.springframework.cloud', name:
'spring-cloud-starter-eureka', version:
'1.3.4.RELEASE'
compile
group:
'org.springframework.cloud', name:
'spring-cloud-config-server', version:
'1.3.2.RELEASE'
compile
group:
'org.springframework.boot', name:
'spring-boot-actuator', version:
'1.5.6.RELEASE'
compile
group:
'org.springframework.boot', name:
'spring-boot-starter-security', version:
'1.5.6.RELEASE'
- 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
server:
port:
8500
eureka:
client:
service-url:
#註冊服務到eureka上,記住這裏要加上eureka-server的用戶名和密碼
defaultZone: http:
instance:
prefer-ip-address:
true
#可能比較長,複製的時候請寫在一行
instance-id: ${spring.application.name}:${spring.cloud.
client.ipAddress}:${spring.application.instance_id:${
server.port}}
appname: springcloud-config-
server
spring:
application:
name: springcloud-config-
server
cloud:
config:
server:
git:
#這是其餘項目配置文件的git倉庫地址
uri: https:
searchPaths:
'{application}'
security:
basic:
enabled:
true
user:
#這是config-server的用戶名和密碼
name: root
password: booszy
修改啓動類,要加入這三個註解,由於要註冊到eureka-server上,因此須要@EnableEurekaClient這個註解
@SpringBootApplication
@EnableConfigServer
@EnableEurekaClient
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
而後運行啓動springboot項目,等啓動成功後訪問eureka的頁面,會發現springcloud-config-server已經註冊到上面了,若是啓動報錯,請檢查錯誤信息。

3、搭建服務提供者服務springcloud-provider-config
編寫一個服務提供者,提供兩個接口,即獲取單個用戶的信息和獲取一個用戶列表。用到了spring-data-jpa 和 spring-webmvc ,固然大家公司用什麼你仍是繼續用什麼。
-
- 注意 : 這裏除了application.xml,還須要一個bootstrap.yml*
-
- 修改build.gradle文件
compile(
'org.springframework.boot:spring-boot-starter-data-jpa')
compile(
'org.springframework.boot:spring-boot-starter-web')
compile(
"com.alibaba:druid-spring-boot-starter:1.1.2")
compile
group:
'org.springframework.cloud', name:
'spring-cloud-starter-eureka', version:
'1.3.4.RELEASE'
compile
group:
'org.springframework.boot', name:
'spring-boot-actuator', version:
'1.5.6.RELEASE'
compile
group:
'org.springframework.cloud', name:
'spring-cloud-starter-config', version:
'1.3.2.RELEASE'
compile
group:
'org.springframework.session', name:
'spring-session-data-redis', version:
'1.3.1.RELEASE'
runtime(
'mysql:mysql-connector-java')
* 注意 : 這裏除了application.xml,還須要一個bootstrap.yml
application.xml我是放到遠程倉庫地址的,你們能夠直接到個人遠程倉庫,根據項目名(springcloud-provider-config)查詢。配置文件的倉庫地址:點擊訪問。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
spring:
application:
name: springcloud
-provider-config
cloud:
config:
#config-server的配置,不須要硬編碼config
-server的地址,使用service
-id去eureka
-server獲取cong
-server的地址
discovery:
enabled:
true
service
-id: springcloud
-config-server
fail
-fast:
true
username: root
password: booszy
profile: dev
eureka:
client:
service
-url:
defaultZone: http:
instance:
prefer
-ip-address:
true
instance
-id: ${spring
.application
.name}:${spring
.cloud
.client
.ipAddress}:${spring
.application
.instance_id:${server
.port}}
appname: springcloud
-provider-config
編寫主類
@SpringBootApplication
@EnableEurekaClient
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
}
新建UserController, 考慮篇幅 UserService 和 UserRepository就不貼代碼了,想看的能夠下載個人代碼。
- 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
@RequestMapping(
"user")
@RestController
public class UserController {
@Autowired
private UserService userService;
/** * @param id * @return */
@GetMapping(
"{id}")
public User
getuser(@PathVariable String id) {
User user =
null;
try {
System.out.println(id);
user = userService.find(id);
}
catch (Exception e) {
e.printStackTrace();
}
return user;
}
/** * @return */
@GetMapping(
"list")
public List<User>
users() {
try {
List<User> user = userService.findAll();
if (user !=
null && user.size() !=
0) {
return user;
}
return null;
}
catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
運行springboot項目,去eureka-server查看,有沒有註冊上。

咱們的springcloud-provider-config已經註冊到eureka上了,訪問接口,成功。

4、搭建消費者服務springcloud-consumer-config-swagger
消費者要訪問服務提供者的服務,這裏用的是經過RestTemplate請求resetful接口,使用ribbon作客戶端負載均衡,hystrix作錯誤處理,swagger生成接口文檔。
仍是熟悉的配方,熟悉的味道,新建springboot項目,添加項目依賴。
compile(
'org.springframework.boot:spring-boot-starter-web')
compile
group:
'org.springframework.cloud', name:
'spring-cloud-starter-eureka', version:
'1.3.4.RELEASE'
compile
group:
'org.springframework.boot', name:
'spring-boot-actuator', version:
'1.5.6.RELEASE'
compile
group:
'org.springframework.cloud', name:
'spring-cloud-starter-config', version:
'1.3.2.RELEASE'
compile
group:
'org.springframework.cloud', name:
'spring-cloud-starter-hystrix', version:
'1.3.4.RELEASE'
compile(
"io.springfox:springfox-swagger2:2.7.0",
"io.springfox:springfox-swagger-ui:2.7.0"
)
application.yml 在git倉庫,請前往git倉庫查看。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
spring:
application:
name: springcloud
-consumer-config
cloud:
config:
discovery:
enabled:
true
service
-id: springcloud
-config-server
fail
-fast:
true
username: root
password: booszy
profile: dev
eureka:
client:
service
-url:
defaultZone: http:
instance:
prefer
-ip-address:
true
instance
-id: ${spring
.application
.name}:${spring
.cloud
.client
.ipAddress}:${spring
.application
.instance_id:${server
.port}}
appname: springcloud
-consumer-config
啓動類代碼
@RibbonClient 指定服務使用的負載均衡類型,name不指定服務則爲全部的服務打開負載均衡,也能夠在用yml中進行配置。
@EnableHystrix 是支持hystrix打開斷路器,在規定時間內失敗參數超過必定參數,就會打開斷路器,不會發起請求,而是直接進入到錯誤處理方法。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
@SpringBootApplication
@EnableEurekaClient
@RibbonClient(name =
"springcloud-provider-config", configuration = RibbonConfiguration.class)
@ComponentScan(excludeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION, value = ExtendRibbon.class)})
@EnableHystrix
public class ConsumerApplication {
@Autowired
private RestTemplateBuilder builder;
@Bean
@LoadBalanced
public RestTemplate
restTemplate() {
return builder.build();
}
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
}
新建UserController
ribbon一個坑,不能接受List類型,要使用數組接收。
@Api xxx 是swagger的註解
@HystrixCommand(fallbackMethod=」userFallbackMethod」)
若是請求失敗,會進入userFallbackMethod這個方法,userFallbackMethod這個方法要求參數和返回值與回調他的方法保持一致。
ribbon這個方法就是經過service-id獲取獲取服務實際的地址,這樣服務的地址就不用硬編碼了。
- 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
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
@Api(
"springcloud consumer user 控制器")
@RequestMapping(
"user")
@RestController
public class UserController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private LoadBalancerClient loadBalancerClient;
/** * @param id * @return */
@ApiOperation(value =
"根據用戶id查詢用戶信息", httpMethod =
"GET", produces =
"application/json")
@ApiResponse(code =
200, message =
"success", response = User.class)
@GetMapping(
"{id}")
@HystrixCommand(fallbackMethod=
"userFallbackMethod")
public User
getUser(@
ApiParam(name =
"id", required =
true, value =
"用戶Id")
@PathVariable String id) {
return this.restTemplate.getForObject(
"http://springcloud-provider-config/user/" + id, User.class);
}
public User
userFallbackMethod(String id){
return null;
}
/** * 這塊ribbon不支持複雜數據類型list,因此要用數組接受,而後轉list * @return */
@GetMapping(
"list")
@HystrixCommand(fallbackMethod =
"userList")
public List<User>
users(HttpServletRequest request) {
try {
User[] forObject =
this.restTemplate.getForObject(
"http://springcloud-provider-config/user/list", User[].class);
List<User> users = Arrays.asList(forObject);
return users ==
null ?
new ArrayList<User>() : users;
}
catch (Exception e) {
e.printStackTrace();
}
return null;
}
public List<User>
userList(HttpServletRequest request) {
return null;
}
/** * 經過服務id獲取服務的地址 * @return */
@GetMapping(
"ribbon")
public String
ribbon(){
ServiceInstance serviceInstance = loadBalancerClient.choose(
"springcloud-provider-config");
return serviceInstance.getUri().toString();
}
}
運行springboot項目,先看有沒有註冊到eureka-server上。

註冊成功後,訪問接口,測試是否正確。

測試swagger-ui,訪問localhost:8200/swagger-ui.html

到這裏消費者服務就算是完成了,後邊你們本身進行擴展。
5、用zuul作路由轉發和負載均衡
這些微服務都是隱藏在後端的,用戶是看不到,或者不是直接接觸,能夠用nginx或者zuul進行路由轉發和負載均衡,zuul負載均衡默認用的是ribbon。
compile
group:
'org.springframework.cloud', name:
'spring-cloud-starter-eureka', version:
'1.3.4.RELEASE'
compile
group:
'org.springframework.cloud', name:
'spring-cloud-starter-zuul', version:
'1.3.4.RELEASE'
compile
group:
'org.springframework.boot', name:
'spring-boot-actuator', version:
'1.5.6.RELEASE'
compile
group:
'org.springframework.cloud', name:
'spring-cloud-starter-config', version:
'1.3.2.RELEASE'
仍是原來的配方,application.yml在git倉庫
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
spring:
application:
name: springcloud
-zuul
cloud:
config:
discovery:
enabled:
true
service
-id: springcloud
-config-server
fail
-fast:
true
username: root
password: booszy
profile: dev
eureka:
client:
service
-url:
defaultZone: http:
instance:
prefer
-ip-address:
true
instance
-id: ${spring
.application
.name}:${spring
.cloud
.client
.ipAddress}:${spring
.application
.instance_id:${server
.port}}
appname: springcloud
-zuul
@RefreshScope這個註解是當application.yml配置文件發生變化的時候,不須要手動的進行重啓,調用localhost:8400/refresh,就會加載新的配置文件,固然正在訪問的客戶並不影響仍是使用舊的配置文件,由於不是重啓,後來的用戶會使用新的配置文件。注意這塊的刷新要用post請求。
@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
@RefreshScope
public class ZuulApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulApplication.class, args);
}
}
啓動springboot項目,訪問eureka-server

這時候,咱們就要經過zuul訪問微服務了,而不是直接去訪問微服務。
應該訪問地址http://192.168.89.89:8400/springcloud-consumer-config/user/list,這塊你要換成你的zuul地址。
可是有些人就會說,這樣之後用戶請求會不會太長,比較反感,因此能夠經過配置進行修改訪問地址。
zuul:
routes:
springcloud-consumer-config:
/consumer/**
springcloud-provider-config:
/provider/**
在application.yml中加入這樣一段配置,其實就是nginx中的反向代理,使用一下簡短的能夠代理這個微服務。這個時候咱們就能夠這樣去訪問了http://192.168.89.89:8400/consumer/user/list,是否是簡短了不少
