有看過我以前的SSM系列的朋友應該有一點印象是很是深入的。前端
那就是須要配置的配置文件很是多,什麼
Spring
、mybatis
、redis
、mq
之類的配置文件很是多,而且還存在各類版本,甚至有些版本還互不兼容。其中有不少可能就是剛開始整合的時候須要配置,以後壓根就不會再動了。java
鑑於此,Spring
又推出了又一神器SpringBoot.git
它可讓咱們更加快速的開發Spring
應用,甚至作到了開箱即用。
因爲在實際開發中咱們使用SpringBoot
+SpringCloud
進行了一段時間的持續交付,並在生產環境獲得了驗證,其中也有很多踩坑的地方,藉此機會和你們分享交流一下。github
本篇咱們首先會用利用SpringBoot
構建出一個簡單的REST API
.
接着會建立另外一個SpringBoot
項目,基於SpringCloud
部署,並在兩個應用之間進行調用。web
SpringBoot
構建REST API
咱們可使用Spring
官方提供的初始化工具幫咱們生成一個基礎項目:start.spring.io/,以下圖所示:
redis
填入相應信息便可。因爲只是要實現REST API
因此這裏只須要引用web
依賴便可。spring
將生成好的項目導入IDE
(我使用的是idea
)中,目錄結構以下;
後端
SbcUserApplication
是整個應用的入口。resource/application.properties
這裏是存放整個應用的配置文件。static
和templates
是存放靜態資源以及前端模板的地方,因爲咱們採用了先後端分離,因此這些目錄基本上用不上了。經過運行SbcUserApplication
類的main
方法能夠啓動SpringBoot
項目。api
接着在PostMan
中進行調用,看到如下結果代表啓動成功了:springboot
這樣一看是否是要比以前用Spring+SpringMVC
來整合要方便快捷不少。
SpringBoot
項目當咱們的項目採用微服務構建以後天然就會被拆分紅N多個獨立的應用。好比上文中的sbc-user
用於用戶管理。這裏再建立一個sbc-order
用戶生成訂單。
爲了方便以後的代碼複用,我將
common
包中的一些枚舉值、工具類單獨提到sbc-common
應用中了,這樣有其餘應用要使用這些基礎類直接引入這個依賴便可。
<dependency>
<groupId>com.crossoverJie</groupId>
<artifactId>sbc-common</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>複製代碼
建立步驟和上文差很少,這裏就再也不贅述了。
其中有一個order/getOrderNo
的服務,調用結果以下:
以後會利用SpringCloud
來將兩個服務關聯起來,並能夠互相調用。
SpringCloud
進行分佈式調用eureka
註冊中心既然是要搭建微服務那天然少不了註冊中心了,以前講的dubbo
採用的是zookeeper
做爲註冊中心,SpringCloud
則採用的是Netflix Eureka
來作服務的註冊與發現。
新建一個項目sbc-service
,目錄結構以下:
核心的pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.1</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Brixton.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>複製代碼
很是easy,只須要引入eureka
的依賴便可。
而後在入口類加入一個註解@EnableEurekaServer
,便可將該項目做爲服務註冊中心:
package com.crossoverJie.service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@EnableEurekaServer
@SpringBootApplication
public class EurekaApplication {
private final static Logger logger = LoggerFactory.getLogger(EurekaApplication.class);
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class, args);
logger.info("SpringBoot Start Success");
}
}複製代碼
接着修改配置文件application.properties
:
server.port=8888
# 不向註冊中心註冊本身
eureka.client.register-with-eureka=false
# 不須要檢索服務
eureka.client.fetch-registry=false
eureka.client.serviceUrl.defaultZone=http://localhost:${server.port}/eureka/複製代碼
配置一下端口以及註冊中心的地址便可。
而後按照正常啓動springBoot
項目同樣啓動便可。
在地址欄輸入http://localhost:8888看到一下界面:
固然如今在註冊中心還看不到任何一個應用,下面須要將上文的sbc-user,sbc-order
註冊進來。
只須要在application.properties
配置文件中加上註冊中心的配置:
eureka.client.serviceUrl.defaultZone=http://localhost:8888/eureka/複製代碼
並在sbc-order
的主類中加入@EnableDiscoveryClient
註解便可完成註冊服務。
啓動註冊中心以及應用,在註冊中心看到一下界面則成功註冊:
服務是註冊上去了,天然是須要消費了,這裏就簡單模擬了在調用http://localhost:8080/user/getUser
這個接口的時候getUser
接口會去調用order
的getOrder
服務。
這裏會用到另外一個依賴:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>複製代碼
他能夠幫咱們作到客戶端負載,具體使用以下:
@LoadBalanced
客戶端負載。restTemplate
類的實例@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}複製代碼
restTemplate
調用遠程服務:@Autowired
private RestTemplate restTemplate;
@RequestMapping(value = "/getUser",method = RequestMethod.POST)
public UserRes getUser(@RequestBody UserReq userReq){
OrderNoReq req = new OrderNoReq() ;
req.setReqNo("1213");
//調用遠程服務
ResponseEntity<Object> res = restTemplate.postForEntity("http://sbc-order/order/getOrderNo", req, Object.class);
logger.info("res="+JSON.toJSONString(res));
logger.debug("入參="+ JSON.toJSONString(userReq));
UserRes userRes = new UserRes() ;
userRes.setUserId(123);
userRes.setUserName("張三");
userRes.setReqNo(userReq.getReqNo());
userRes.setCode(StatusEnum.SUCCESS.getCode());
userRes.setMessage("成功");
return userRes ;
}複製代碼
因爲個人遠程接口是post
,因此使用了postForEntity()
方法,若是是get
就換成getForEntity()
便可。
注意這裏是使用應用名
sbc-order(配置於sbc-order的application.properties中)
來進行調用的,並非一個IP地址。
啓動註冊中心、兩個應用。
用PostMan
調用getUser
接口時控制檯打印:
2017-06-27 00:18:04.534 INFO 63252 --- [nio-8080-exec-3] c.c.sbcuser.controller.UserController : res={"body":{"code":"4000","message":"appID不能爲空","reqNo":"1213"},"headers":{"X-Application-Context":["sbc-order:8181"],"Content-Type":["application/xml;charset=UTF-8"],"Transfer-Encoding":["chunked"],"Date":["Mon, 26 Jun 2017 16:18:04 GMT"]},"statusCode":"OK","statusCodeValue":200}複製代碼
因爲並無傳遞appId
因此order
服務返回了一個錯誤,也正說明是遠程調用到了該服務。
ps:這裏只是簡單使用了
ribbon
來進行服務調用,但在實際的開發中仍是比較少的使用這種方式來調用遠程服務,而是使用Feign
進行聲明式調用,能夠簡化客戶端代碼,具體使用方式請持續關注。
本次算是springBoot+springCloud
的入門,還有不少東西沒有講到,以後我將會根據實際使用的一些經驗繼續分享SpringCloud
這個新興框架。
我的博客地址:crossoverjie.top。