想對(duì)看過(guò)的spring cloud 各個(gè)項(xiàng)目進(jìn)行一個(gè)簡(jiǎn)單的搭建砚亭,并使用docker部署曾棕,目前包含的項(xiàng)目有Eureka扣猫、Ribbon、Feign翘地、Hystrix申尤、Hystrix Dashboard、Turbine聚合監(jiān)控衙耕、Zuul昧穿、SpringBootAdmin等Spring Config 、OAuth2未集成進(jìn)來(lái)橙喘,但是在我的主頁(yè)里有單獨(dú)的實(shí)例时鸵,后續(xù)會(huì)慢慢都集成進(jìn)來(lái)。
github地址:https://github.com/liangxiaobo/springbootcloud-all 分支 master-docker
項(xiàng)目模塊:
├── client-common-dependencys
├── client-feign
├── client-gateway-zuul
├── client-order-ribbon
├── client-turbine-monitor
├── docker-compose-base.yml
├── docker-compose.yml
├── docker-start.sh
├── docker-zipkin-shell.sh
├── eureka-server
├── mvn-package-docker.sh
├── pom.xml
├── service-common-dependencys
├── service-order
├── service-user
├── spring-boot-admin-server
├── springbootdemoall.iml
├── src
├── swagger-doc
└── var
項(xiàng)目 | 端口 | 描述 |
---|---|---|
eureka-server | 8761 | 服務(wù)的注冊(cè)與發(fā)現(xiàn) |
service-user | 8763 | 服務(wù)提供者 |
service-order | 8764 | 服務(wù)提供者 |
client-feign | 8765 | 負(fù)載均衡 Feign |
client-order-ribbon | 8766 | 負(fù)載均衡 Ribbon |
client-gateway-zuul | 8771 | 網(wǎng)關(guān) Zuul |
client-turbine-monitor | 8767 | Turbine聚合監(jiān)控 |
swagger-doc | 8772 | 生成在線Api |
spring-boot-admin-server | 8773 | spring-boot-admin-server |
項(xiàng)目中看到兩個(gè)項(xiàng)目 service-common-dependencys和client-common-dependencys是pom項(xiàng)目厅瞎,用來(lái)測(cè)試統(tǒng)一管理引用依賴的項(xiàng)目(分別是service項(xiàng)目和client項(xiàng)目的父類)饰潜;
當(dāng)父類pom用dependencies來(lái)管理依賴的話初坠,那么子項(xiàng)目必須繼承所有依賴
當(dāng)父類pom用dependencyManagement來(lái)管理依賴的話,那么子項(xiàng)目不是必須繼承囊拜,而是有選擇的引用依賴某筐;我這里使用的是前者
eureka-server 項(xiàng)目 參照 spring cloud 搭建集群Eureka Server
spring-boot-admin-server 參照 SpringBoot Admin 2.0
client-roder-ribbon 參照 使用RestTemplate和Ribbon來(lái)消費(fèi)服務(wù)和Hystrix熔斷功能
service-user比搭、service-order 就是簡(jiǎn)單的web項(xiàng)目
Feign項(xiàng)目 client-feign
Feign是一個(gè)聲明式的Web Service客戶端冠跷,它使得編寫Web Serivce客戶端變得更加簡(jiǎn)單。我們只需要使用Feign來(lái)創(chuàng)建一個(gè)接口并用注解來(lái)配置它既可完成身诺。它具備可插拔的注解支持蜜托,包括Feign注解和JAX-RS注解。Feign也支持可插拔的編碼器和解碼器霉赡。Spring Cloud為Feign增加了對(duì)Spring MVC注解的支持橄务,還整合了Ribbon和Eureka來(lái)提供均衡負(fù)載的HTTP客戶端實(shí)現(xiàn)。
依賴pom.xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
pom中引用了父類 ,繼承父類的所有依賴穴亏,其中有Hystrix蜂挪、admin-client、eureka等
<parent>
<groupId>com.spring.nahong.client.common.dependency</groupId>
<artifactId>client-common-dependencys</artifactId>
<version>${all.version}</version>
<relativePath>../client-common-dependencys</relativePath>
</parent>
看一下啟動(dòng)類
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
@EnableHystrixDashboard
public class ClientFeignApplication {
public static void main(String[] args) {
SpringApplication.run(ClientFeignApplication.class, args);
}
/**
* springboot 版本如果是2.0則需要添加 ServletRegistrationBean
* 因?yàn)閟pringboot的默認(rèn)路徑不是 "/hystrix.stream"嗓化,
* 只要在自己的項(xiàng)目里配置上下面的servlet就可以了
* 第一次訪問(wèn)hystrix.stream 會(huì)出現(xiàn) Unable to connect to Command Metric Stream
*/
@Bean
public ServletRegistrationBean getServlet() {
HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
registrationBean.setLoadOnStartup(1);
registrationBean.addUrlMappings("/hystrix.stream");
registrationBean.setName("HystrixMetricsStreamServlet");
return registrationBean;
}
}
@EnableFeignClients 開啟了feign @EnableHystrixDashboard開啟了熔斷hystrix的界面
定義Feign接口UserClientFeign
@FeignClient(value = "service-user", configuration = FeignConfig.class, fallback = UserHystrix.class)
public interface UserClientFeign {
@GetMapping("/user/say")
String sayFromClient(@RequestParam("name") String name);
}
上面聲明了指向service-user服務(wù) UserHystrix是對(duì)應(yīng)的熔斷類
@Component
public class UserHystrix implements UserClientFeign {
@Override
public String sayFromClient(String name) {
return "hi , sorry error!";
}
}
定義一個(gè)服務(wù)UserService
@Service
public class UserService {
@Autowired
UserClientFeign userClientFeign;
public String say(String name) {
return userClientFeign.sayFromClient(name);
}
}
聲明一個(gè)Feign的配置類FeignConfig
@Configuration
public class FeignConfig {
@Bean
public Retryer feignRetryer() {
return new Retryer.Default(100, SECONDS.toMillis(1), 5);
}
}
創(chuàng)建一個(gè)UserController
@RestController
public class UserController {
@Autowired
UserService userService;
@RequestMapping("/user/hi")
public String say(@RequestParam("name") String name) {
return userService.say(name);
}
}
啟用Feign的hystrix最重要的是在配置文件中添加
feign:
hystrix:
enabled: true
可以啟動(dòng) eureka-server service-user client-feign 訪問(wèn)http://localhost:8765/user/hi?name=liajngbo
如果測(cè)試負(fù)載均衡功能可以多運(yùn)行一個(gè)service-user用不同的端口8863棠涮,然后在瀏覽器刷新 http://localhost:8765/user/hi?name=liajngbo 會(huì)發(fā)現(xiàn)有不同的結(jié)果
Hi, my name is liajngbo, port: 8763
Hi, my name is liajngbo, port: 8863
client-feign項(xiàng)目中已經(jīng)配置了hystrix,現(xiàn)在訪問(wèn)http://localhost:8765/hystrix
在輸入框中輸入http://localhost:8765/hystrix.stream點(diǎn)擊按扭
Turbine項(xiàng)目 client-turbine-monitor
Turbine能夠匯集監(jiān)控信息刺覆,并將聚合后的信息提供給Hystrix Dashboard來(lái)集中展示和監(jiān)控严肪。
項(xiàng)目配置起來(lái)相當(dāng)簡(jiǎn)單,只是2.0版本會(huì)有點(diǎn)小坑
pom.xml全部代碼請(qǐng)參閱源碼(源碼包含了admin-client的依賴)這只是turbine的依賴:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-turbine</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
啟動(dòng)類:
@SpringBootApplication
@EnableTurbine
@EnableHystrixDashboard
public class ClientTurbineMonitorApplication {
public static void main(String[] args) {
SpringApplication.run(ClientTurbineMonitorApplication.class, args);
}
}
@EnableTurbine 開啟了turbine功能谦屑,@EnableHystrixDashboard開啟了hystrix監(jiān)控UI
一般的配置文件:
turbine:
app-config: client-feign,client-order-ribbon,client-gateway-zuul # 指定了要監(jiān)控的應(yīng)用名字
cluster-name-expression: new String("default") # 表示集群的名字為default
combine-host-port: true # 表示同一主機(jī)上的服務(wù)通過(guò)host和port的組合來(lái)進(jìn)行區(qū)分驳糯,默認(rèn)情況下是使用host來(lái)區(qū)分,這樣會(huì)使本地調(diào)試有問(wèn)題
這里會(huì)有一個(gè)問(wèn)題氢橙,turbine會(huì)去訪問(wèn)其它項(xiàng)目的/hystrix.stream路徑酝枢,默認(rèn)情況下turbine訪問(wèn)的是/actuator/hystrix.stream,這個(gè)路徑訪問(wèn)不通悍手,因?yàn)槠渌?xiàng)目注冊(cè)的路由地址是/hystrix.stream帘睦,所以要糾正turbine項(xiàng)目訪問(wèn)的默認(rèn)地址,在配置文件中添加turbine.instanceUrlSuffix=hystrix.stream谓苟,management.context-path=/
配置文件:
management:
context-path: /
turbine:
app-config: client-feign,client-order-ribbon,client-gateway-zuul # 指定了要監(jiān)控的應(yīng)用名字
cluster-name-expression: new String("default") # 表示集群的名字為default
combine-host-port: true # 表示同一主機(jī)上的服務(wù)通過(guò)host和port的組合來(lái)進(jìn)行區(qū)分官脓,默認(rèn)情況下是使用host來(lái)區(qū)分,這樣會(huì)使本地調(diào)試有問(wèn)題
instanceUrlSuffix: hystrix.stream
測(cè)試一下turbine,必須啟動(dòng)多個(gè)項(xiàng)目 eureka-server涝焙、service-user卑笨、service-order、client-feign仑撞、client-order-ribbon赤兴、client-gateway-zuul妖滔、client-turbine-monitor
訪問(wèn)turbine之前要先訪問(wèn)一下其它項(xiàng)目,不然不會(huì)有數(shù)據(jù)顯示turbine會(huì)處于loading中
訪問(wèn) http://localhost:8767/turbine.stream 會(huì)有json格式的數(shù)據(jù)流
{"rollingCountFallbackSuccess":0,"rollingCountFallbackFailure":0,"propertyValue_circuitBreakerRequestVolumeThreshold":20,"propertyValue_circuitBreakerForceOpen":false,"propertyValue_metricsRollingStatisticalWindowInMilliseconds":10000,"latencyTotal_mean":10,"rollingMaxConcurrentExecutionCount":0,"type":"HystrixCommand","rollingCountResponsesFromCache":0,"rollingCountBadRequests":0,"rollingCountTimeout":0,"propertyValue_executionIsolationStrategy":"THREAD","rollingCountFailure":0,"rollingCountExceptionsThrown":0,"rollingCountFallbackMissing":0,"threadPool":"service-user","latencyExecute_mean":10,"isCircuitBreakerOpen":false,"errorCount":0,"rollingCountSemaphoreRejected":0,"group":"service-user","latencyTotal":{"0":10,"99":10,"100":10,"25":10,"90":10,"50":10,"95":10,"99.5":10,"75":10},"requestCount":0,"rollingCountCollapsedRequests":0,"rollingCountShortCircuited":0,"propertyValue_circuitBreakerSleepWindowInMilliseconds":5000,"latencyExecute":{"0":10,"99":10,"100":10,"25":10,"90":10,"50":10,"95":10,"99.5":10,"75":10},"rollingCountEmit":0,"currentConcurrentExecutionCount":0,"propertyValue_executionIsolationSemaphoreMaxConcurrentRequests":10,"errorPercentage":0,"rollingCountThreadPoolRejected":0,"propertyValue_circuitBreakerEnabled":true,"propertyValue_executionIsolationThreadInterruptOnTimeout":true,"propertyValue_requestCacheEnabled":true,"rollingCountFallbackRejection":0,"propertyValue_requestLogEnabled":true,"rollingCountFallbackEmit":0,"rollingCountSuccess":0,"propertyValue_fallbackIsolationSemaphoreMaxConcurrentRequests":10,"propertyValue_circuitBreakerErrorThresholdPercentage":50,"propertyValue_circuitBreakerForceClosed":false,"name":"UserClientFeign#sayFromClient(String)","reportingHosts":1,"propertyValue_executionIsolationThreadPoolKeyOverride":"null","propertyValue_executionIsolationThreadTimeoutInMilliseconds":1000,"propertyValue_executionTimeoutInMilliseconds":1000}
data: {"currentCorePoolSize":10,"currentLargestPoolSize":2,"propertyValue_metricsRollingStatisticalWindowInMilliseconds":10000,"currentActiveCount":0,"currentMaximumPoolSize":10,"currentQueueSize":0,"type":"HystrixThreadPool","currentTaskCount":2,"currentCompletedTaskCount":2,"rollingMaxActiveThreads":0,"rollingCountCommandRejections":0,"name":"service-user","reportingHosts":1,"currentPoolSize":2,"propertyValue_queueSizeRejectionThreshold":5,"rollingCountThreadsExecuted":0}
訪問(wèn)hystrix UI http://localhost:8767/hystrix
網(wǎng)關(guān)Zuul client-gateway-zuul
項(xiàng)目依賴桶良,完整的pom.xml中包含了其它的依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
啟動(dòng)類:
@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
@EnableHystrixDashboard
public class ClientGatewayZuulApplication {
public static void main(String[] args) {
SpringApplication.run(ClientGatewayZuulApplication.class, args);
}
/**
* springboot 版本如果是2.0則需要添加 ServletRegistrationBean
* 因?yàn)閟pringboot的默認(rèn)路徑不是 "/hystrix.stream"座舍,
* 只要在自己的項(xiàng)目里配置上下面的servlet就可以了
* 第一次訪問(wèn)hystrix.stream 會(huì)出現(xiàn) Unable to connect to Command Metric Stream
*
*/
@Bean
public ServletRegistrationBean getServlet() {
HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
registrationBean.setLoadOnStartup(1);
registrationBean.addUrlMappings("/hystrix.stream");
registrationBean.setName("HystrixMetricsStreamServlet");
return registrationBean;
}
}
開啟網(wǎng)關(guān)zuul @EnableZuulProxy
@EnableEurekaClient 開啟eureka客戶端
@EnableHystrixDashboard Hystrix Dashboard
主要配置:
zuul:
routes:
hiapi:
path: /hiapi/**
serviceId: service-user
ribbonapi:
path: /ribbonapi/**
serviceId: client-order-ribbon
feignapi:
path: /feignapi/**
serviceId: client-feign
prefix: /v1
routes下面是路由,hiapi陨帆、ribbonapi曲秉、feignapi是自定義路由名稱,下面path是路由規(guī)則疲牵,serviceId指定服務(wù)名稱承二,prefix給路由加上前綴
注意:因?yàn)轫?xiàng)目是我寫好的demo,其中包含了hystrix功能纲爸,在/hystrix中Thread Pools會(huì)一直處于loading狀態(tài)亥鸠,這是由于Zuul默認(rèn)會(huì)使用信號(hào)量來(lái)實(shí)現(xiàn)隔離,只有通過(guò)Hystrix配置把隔離機(jī)制改成為線程池的方式才能夠得以展示识啦,
SEMAPHORE - 它在調(diào)用線程上執(zhí)行负蚊,并發(fā)請(qǐng)求受信號(hào)量計(jì)數(shù)的限制(Zuul默認(rèn)此策略)
THREAD - 它在一個(gè)單獨(dú)的線程上執(zhí)行,并發(fā)請(qǐng)求受到線程池中線程數(shù)的限制
配置文件中添加
thread-pool:
use-separate-thread-pools: true
ribbon-isolation-strategy: thread # 每個(gè)路由使用獨(dú)立的線程池
Zuul中提供Filter的作用有哪些颓哮,我覺得分為如下幾點(diǎn):
- 網(wǎng)關(guān)是暴露在外面的家妆,必須要進(jìn)行權(quán)限控制
- 可以針對(duì)服務(wù)做控制,在路由的時(shí)候處理题翻,比如服務(wù)降級(jí)
- 防止爬蟲揩徊,利用Filter對(duì)請(qǐng)求進(jìn)行過(guò)濾
- 流量控制,只允許最高的并發(fā)量嵌赠,保護(hù)后端的服務(wù)
- 灰度發(fā)布塑荒,可以針對(duì)不用的用戶進(jìn)行路由來(lái)實(shí)現(xiàn)灰度
Filter種類
- pre:可以在請(qǐng)求被路由之前調(diào)用
- route:在路由請(qǐng)求時(shí)候被調(diào)用
- post:在route和error過(guò)濾器之后被調(diào)用
- error:處理請(qǐng)求時(shí)發(fā)生錯(cuò)誤時(shí)被調(diào)用
zuul的Filter的生命周期,見下圖:
創(chuàng)建一個(gè)Filter類MyFilter姜挺,filterType類型為"pre":
@Component
public class MyFilter extends ZuulFilter {
private static Logger logger = LoggerFactory.getLogger(MyFilter.class);
@Override
public String filterType() {
return FilterConstants.PRE_TYPE; // pre
}
@Override
public int filterOrder() {
return 0;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() throws ZuulException {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
Object accessToken = request.getParameter("token");
if (accessToken == null) {
logger.warn("token is empty");
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(401);
try {
ctx.getResponse().getWriter().write("token is empty");
}catch (Exception e) {
return null;
}
}
logger.info("ok");
return null;
}
}
shouldFilter是決定這個(gè)過(guò)濾器需不需要執(zhí)行齿税,返回false則不執(zhí)行,這個(gè)也可以利用配置中心來(lái)做炊豪,達(dá)到動(dòng)態(tài)的開啟關(guān)閉效果凌箕,
filterOrder是表示過(guò)濾器執(zhí)行的順序,數(shù)字越小词渤,優(yōu)先級(jí)越高
run里面就是我們自己要執(zhí)行的業(yè)務(wù)邏輯牵舱,這里我們驗(yàn)證了一下接口參數(shù)中有沒(méi)有token
zuul自身是集成了hystrix的,所以它帶有熔斷功能
創(chuàng)建一個(gè)ServiceUserFallbackProvider類實(shí)現(xiàn)接口FallbackProvider缺虐,實(shí)現(xiàn)service-user的熔斷功能:
@Component
public class ServiceUserFallbackProvider implements FallbackProvider {
static final Logger logger = LoggerFactory.getLogger(ServiceUserFallbackProvider.class);
@Override
public String getRoute() {
// 表明是為哪個(gè)微服務(wù)提供回退芜壁,*表示為所有微服務(wù)提供回退,當(dāng)前只為service-user提供
return "service-user";
}
@Override
public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
logger.info("route: " + route);
return new ClientHttpResponse() {
@Override
public HttpStatus getStatusCode() throws IOException {
return HttpStatus.OK;
}
@Override
public int getRawStatusCode() throws IOException {
return 200;
}
@Override
public String getStatusText() throws IOException {
return "OK";
}
@Override
public void close() {
}
@Override
public InputStream getBody() throws IOException {
return new ByteArrayInputStream("oooops! error,i'm the fallback.".getBytes());
}
@Override
public HttpHeaders getHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
return headers;
}
};
}
}
啟動(dòng)eureka-server、service-user慧妄、service-order顷牌、client-feign、client-order-ribbon塞淹、client-gateway-zuul窟蓝,訪問(wèn)http://localhost:8771/v1/hiapi/user/say?name=liang&token=123
正常結(jié)果顯示:
Hi, my name is liang, port: 8763
去掉token訪問(wèn):http://localhost:8771/v1/hiapi/user/say?name=liang
token is empty
測(cè)試熔斷效果,關(guān)停service-user項(xiàng)目 訪問(wèn): http://localhost:8771/v1/hiapi/user/say?name=liang&token=123
oooops! error,i'm the fallback.
使用docker部署項(xiàng)目
Docker是一個(gè)用于開發(fā)饱普、交付和運(yùn)行應(yīng)用的開放平臺(tái)运挫,Docker被設(shè)計(jì)用于更快地交付應(yīng)用。Docker可以將應(yīng)用程序和基礎(chǔ)設(shè)施層隔離费彼,并且可以將基礎(chǔ)設(shè)施當(dāng)作程序一樣進(jìn)行管理滑臊。使用Docker,可以更快地打包代碼箍铲、測(cè)試以及部署,并且可以減少?gòu)木帉懙讲渴疬\(yùn)行代碼的周期鬓椭。
Docker將內(nèi)核容器特性(LXC)颠猴、工作流和工具集成,以幫助管理和部署應(yīng)用小染。
什么是Docker
核心是翘瓮,Docker是一種在安全隔離的容器中運(yùn)行近乎所有應(yīng)用的方式,這種隔離性和安全性允許你在同一個(gè)主機(jī)上同時(shí)運(yùn)行多個(gè)容器裤翩,而容器的這種輕量級(jí)特性资盅,無(wú)需消耗運(yùn)行hpervisor所需的額外負(fù)載,意味著你可以節(jié)省更多的硬件資源踊赠。
docker如何安裝這里不講呵扛,自行解決
這里演示在單臺(tái)宿主機(jī)上的測(cè)試結(jié)果
因?yàn)轫?xiàng)目是我提前寫好的項(xiàng)目,可以看到項(xiàng)目中的pom文件中有:
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>${docker.plugin.version}</version>
<configuration>
<imageName>${docker.image.prefix}/${project.artifactId}</imageName>
<dockerDirectory>src/main/docker</dockerDirectory>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
<imageTags>
<!--<imageTag>${project.version}</imageTag>-->
<imageTag>latest</imageTag>
</imageTags>
</configuration>
</plugin>
${docker.image.prefix}是我在父類中定義的liangwang
imageName是鏡像名稱
dockerDirectory是Dockerfile路徑
resources是資源的配置筐带,jar所在的目錄
imageTags是鏡像的tag版本的意思今穿,image:[tag]
Dockerfile
FROM java
VOLUME /tmp
ADD eureka-server-0.0.1-SNAPSHOT.jar app.jar
#RUN bash -c 'touch /app.jar'
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","-Dspring.profiles.active=${SPRING_PROFILES_ACTIVE}","/app.jar"]
EXPOSE 8761 # 開放的端口
EXPOSE 是開放的端口 多個(gè)端口可以以空格隔開 "8761 8762 8763"
ENTRYPOINT 是容器啟動(dòng)后執(zhí)行的命令
springboot打包的項(xiàng)目jar的運(yùn)行命令 "java -jar app.jar" 如果啟用不同的配置文件的話要 “java -jar app.jar --spring.profiles.active=test”,所以上面定義了一個(gè)變量來(lái)接收容器啟動(dòng)設(shè)置的參數(shù)SPRING_PROFILES_ACTIVE 容器啟動(dòng)時(shí)加 -e "SPRING_PROFILES_ACTIVE=test"
maven 打包 docker 命令
mvn clean package docker:build -Dmaven.test.skip=true
# -Dmaven.test.skip 跳過(guò)單元測(cè)試
容器啟動(dòng):
docker run -d -e "SPRING_PROFILES_ACTIVE=test-peer1" --name eureka-server -p 8761:8761 -it liangwang/eureka-server
同一臺(tái)宿主機(jī)可以使用容器名稱來(lái)通信 比如 eureka-server容器使用link參數(shù)將其它鏈接到容器2
docker run -d -e "SPRING_PROFILES_ACTIVE=test" --name service-user-01 --link=eureka-server -p 8763:8763 -it liangwang/service-user
對(duì)于注冊(cè)與發(fā)現(xiàn)服務(wù),eureka-server和其它eureka-client中的 serviceUri.defaultZone=http://eureka-server:8761/eureka/
例舉各別:
eureka-server的配置文件
spring:
profiles: test-peer1
application:
name: eureka-server
server:
port: 8761
eureka:
instance:
prefer-ip-address: true
hostname: eureka-server
instance-id: ${spring.cloud.client.ipAddress}:${server.port}
client:
service-url:
defaultZone: http://eureka-server:8761/eureka/ # 注意客戶端中也使用eureka-server
register-with-eureka: false
fetch-registry: false
下面可以按順序打包項(xiàng)目:
項(xiàng)目根目錄中有一個(gè)mvn-package-docker.sh
#!/bin/bash
echo "開始執(zhí)行打包....[start]"
mvn clean
cd eureka-server
mvn package docker:build -Dmaven.test.skip=true
cd ../service-user
mvn package docker:build -Dmaven.test.skip=true
cd ../service-order
mvn package docker:build -Dmaven.test.skip=true
cd ../spring-boot-admin-server
mvn package docker:build -Dmaven.test.skip=true
cd ../client-feign
mvn package docker:build -Dmaven.test.skip=true
cd ../client-order-ribbon
mvn package docker:build -Dmaven.test.skip=true
cd ../client-gateway-zuul
mvn package docker:build -Dmaven.test.skip=true
cd ../client-turbine-monitor
mvn package docker:build -Dmaven.test.skip=true
cd ../swagger-doc
mvn package docker:build -Dmaven.test.skip=true
echo "執(zhí)行打包結(jié)束.....[end]"
也可以手動(dòng)打包各別你想打包的項(xiàng)目
打包完之后伦籍,執(zhí)行命令 docker images
[root@swarm03 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
liangwang/swagger-doc latest 9d477baa8695 2 days ago 689MB
liangwang/client-turbine-monitor latest bb26593b2683 2 days ago 692MB
liangwang/client-gateway-zuul latest a2148967a806 2 days ago 693MB
liangwang/client-order-ribbon latest 71a24105d743 2 days ago 693MB
liangwang/client-feign latest 6ae21d5dab6d 2 days ago 693MB
liangwang/spring-boot-admin-server latest 6d9314544f13 2 days ago 697MB
liangwang/service-order latest 48b8fd2e0de4 2 days ago 691MB
liangwang/service-user latest f33c40c5b79a 2 days ago 691MB
liangwang/eureka-server latest f5e714d47a6f 2 days ago 691MB
java latest d23bdf5b1b1b 20 months ago 643MB
除java之外都是打包生成的鏡像
下面要運(yùn)行容器來(lái)跑這些鏡像蓝晒,項(xiàng)目根目錄有一個(gè)docker-start.sh腳本,里面是跑各個(gè)容器的命令帖鸦,最好不要執(zhí)行這個(gè)腳本芝薇,因?yàn)闆](méi)有時(shí)間停頓,所以容器全部運(yùn)行沒(méi)有前后順序作儿,如果eureka-server沒(méi)有跑起來(lái)洛二,可能其它項(xiàng)目會(huì)報(bào)錯(cuò),最好先手動(dòng)一條一條執(zhí)行,這里是演示測(cè)試所以沒(méi)有用容器編排
# eureka-server docker 啟動(dòng)命令:
docker run -d -e "SPRING_PROFILES_ACTIVE=test-peer1" --name eureka-server -p 8761:8761 -it liangwang/eureka-server
# service-user-01 docker 啟動(dòng)命令:
docker run -d -e "SPRING_PROFILES_ACTIVE=test" --name service-user-01 --link=eureka-server -p 8763:8763 -it liangwang/service-user
# service-user-02 docker 啟動(dòng)命令:
docker run -d -e "SPRING_PROFILES_ACTIVE=test" --name service-user-02 --link=eureka-server -p 8863:8863 -it liangwang/service-user --server.port=8863
# service-order-01 docker 啟動(dòng)命令:
docker run -d -e "SPRING_PROFILES_ACTIVE=test" --name service-order-01 --link=eureka-server -p 8764:8764 -it liangwang/service-order
# service-order-02 docker 啟動(dòng)命令:
docker run -d -e "SPRING_PROFILES_ACTIVE=test" --name service-order-02 --link=eureka-server -p 8864:8864 -it liangwang/service-order --server.port=8864
# spring-boot-admin-server docker 啟動(dòng)命令:
docker run -d -e "SPRING_PROFILES_ACTIVE=test" --name spring-boot-admin-server --link=eureka-server -p 8773:8773 -it liangwang/spring-boot-admin-server
# client-feign docker 啟動(dòng)命令:
docker run -d -e "SPRING_PROFILES_ACTIVE=test" --name client-feign --link=eureka-server -p 8765:8765 -it liangwang/client-feign
# client-order-ribbon docker 啟動(dòng)命令:
docker run -d -e "SPRING_PROFILES_ACTIVE=test" --name client-order-ribbon --link=eureka-server -p 8766:8766 -it liangwang/client-order-ribbon
# client-gateway-zuul docker 啟動(dòng)命令:
docker run -d -e "SPRING_PROFILES_ACTIVE=test" --name client-gateway-zuul --link=eureka-server -p 8771:8771 -it liangwang/client-gateway-zuul
# client-turbine-monitor docker 啟動(dòng)命令:
docker run -d -e "SPRING_PROFILES_ACTIVE=test" --name client-turbine-monitor --link=eureka-server -p 8767:8767 -it liangwang/client-turbine-monitor
# swagger-doc docker 啟動(dòng)命令:
docker run -d -e "SPRING_PROFILES_ACTIVE=test" --name swagger-doc --link=eureka-server -p 8772:8772 -it liangwang/swagger-doc
沒(méi)有問(wèn)題的情況下灭红,執(zhí)行docker ps能看到正在運(yùn)行的容器進(jìn)程
[root@swarm03 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0c70c83fd5f2 liangwang/client-turbine-monitor "java -Djava.secur..." 2 days ago Up 2 days 0.0.0.0:8767->8767/tcp client-turbine-monitor
1b78c139bded liangwang/client-gateway-zuul "java -Djava.secur..." 2 days ago Up 2 days 0.0.0.0:8771->8771/tcp client-gateway-zuul
1582be4ac882 liangwang/client-order-ribbon "java -Djava.secur..." 2 days ago Up 2 days 0.0.0.0:8766->8766/tcp client-order-ribbon
d13d2fdf24ae liangwang/client-feign "java -Djava.secur..." 2 days ago Up 2 days 0.0.0.0:8765->8765/tcp client-feign
3f149a4873cf liangwang/spring-boot-admin-server "java -Djava.secur..." 2 days ago Up 2 days 0.0.0.0:8773->8773/tcp spring-boot-admin-server
399150b6fa6e liangwang/service-order "java -Djava.secur..." 2 days ago Up 2 days 8764/tcp, 0.0.0.0:8864->8864/tcp service-order-02
e7ffefe94d3e liangwang/service-order "java -Djava.secur..." 2 days ago Up 2 days 0.0.0.0:8764->8764/tcp service-order-01
9be1cabe9b5a liangwang/service-user "java -Djava.secur..." 2 days ago Up 2 days 8763/tcp, 0.0.0.0:8863->8863/tcp service-user-02
7b82a04ddbeb liangwang/service-user "java -Djava.secur..." 2 days ago Up 2 days 0.0.0.0:8763->8763/tcp service-user-01
ee0fdbee9f33 liangwang/eureka-server "java -Djava.secur..." 2 days ago Up 2 days 0.0.0.0:8761->8761/tcp eureka-server
這時(shí)候訪問(wèn) http://localhost:8761侣滩,我項(xiàng)目部署在測(cè)試服務(wù)器所以我的訪問(wèn)地址為 http://172.16.10.177:8761/
能看到項(xiàng)目都已經(jīng)注冊(cè)進(jìn)來(lái)了
看admin-server 訪問(wèn)http://localhost:8773,我的訪問(wèn)地址為 http://172.16.10.177:8773
改造項(xiàng)目增加zipkin鏈路追蹤
使用鏡像運(yùn)行zipkin項(xiàng)目
請(qǐng)先拉取鏡像
docker pull openzipkin/zipkin
# 運(yùn)行容器
# docker run -d -p 9411:9411 -e MYSQL_USER=root -e MYSQL_PASS=password -e MYSQL_HOST=192.168.0.8 -e STORAGE_TYPE=mysql openzipkin/zipkin
docker run -d -p 9411:9411 --name zipkin openzipkin/zipkin
在需要追蹤的項(xiàng)目中添加依賴
<!-- 鏈路追蹤 zipkin -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
在application.yml中添加
spring:
zipkin:
base-url: http://localhost:9411 # 如果zipkin服務(wù)在其它服務(wù)器变擒,localhost應(yīng)為對(duì)應(yīng)的IP
sleuth:
sampler:
probability: 1.0
sleuth.sampler.probability 是監(jiān)控的百分比君珠,默認(rèn)的是0.1表示10%,這里給1.0表示全部監(jiān)控
spring.zipkin.base-url:是zipkin-server的服務(wù)路徑
訪問(wèn) http://localhost:9411
后續(xù)我會(huì)集成OAuth2.0 JWT和Config配置中心