spring cloud 快速学习教程

想对看过的spring cloud 各个项目进行一个简单的搭建,并使用docker部署,目前包含的项目有Eureka、Ribbon、Feign、Hystrix、Hystrix Dashboard、Turbine聚合监控、Zuul、SpringBootAdmin等Spring Config 、OAuth2未集成进来,但是在我的主页里有单独的实例,后续会慢慢都集成进来。

github地址:https://github.com/liangxiaobo/springbootcloud-all 分支 master-docker

项目模块:

├── 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
项目 端口 描述
eureka-server 8761 服务的注册与发现
service-user 8763 服务提供者
service-order 8764 服务提供者
client-feign 8765 负载均衡 Feign
client-order-ribbon 8766 负载均衡 Ribbon
client-gateway-zuul 8771 网关 Zuul
client-turbine-monitor 8767 Turbine聚合监控
swagger-doc 8772 生成在线Api
spring-boot-admin-server 8773 spring-boot-admin-server

项目中看到两个项目 service-common-dependencys和client-common-dependencys是pom项目,用来测试统一管理引用依赖的项目(分别是service项目和client项目的父类);

当父类pom用dependencies来管理依赖的话,那么子项目必须继承所有依赖
当父类pom用dependencyManagement来管理依赖的话,那么子项目不是必须继承,而是有选择的引用依赖;我这里使用的是前者

eureka-server 项目 参照 spring cloud 搭建集群Eureka Server
spring-boot-admin-server 参照 SpringBoot Admin 2.0
client-roder-ribbon 参照 使用RestTemplate和Ribbon来消费服务和Hystrix熔断功能
service-user、service-order 就是简单的web项目

Feign项目 client-feign

Feign是一个声明式的Web Service客户端,它使得编写Web Serivce客户端变得更加简单。我们只需要使用Feign来创建一个接口并用注解来配置它既可完成。它具备可插拔的注解支持,包括Feign注解和JAX-RS注解。Feign也支持可插拔的编码器和解码器。Spring Cloud为Feign增加了对Spring MVC注解的支持,还整合了Ribbon和Eureka来提供均衡负载的HTTP客户端实现。
依赖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>

看一下启动类

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
@EnableHystrixDashboard
public class ClientFeignApplication {

    public static void main(String[] args) {
        SpringApplication.run(ClientFeignApplication.class, args);
    }

    /**
     * springboot 版本如果是2.0则需要添加 ServletRegistrationBean
     * 因为springboot的默认路径不是 "/hystrix.stream",
     * 只要在自己的项目里配置上下面的servlet就可以了
     * 第一次访问hystrix.stream 会出现 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服务 UserHystrix是对应的熔断类

@Component
public class UserHystrix implements UserClientFeign {

    @Override
    public String sayFromClient(String name) {
        return "hi , sorry error!";
    }
}

定义一个服务UserService

@Service
public class UserService {
    @Autowired
    UserClientFeign userClientFeign;

    public String say(String name) {
        return userClientFeign.sayFromClient(name);
    }
}

声明一个Feign的配置类FeignConfig

@Configuration
public class FeignConfig {

    @Bean
    public Retryer feignRetryer() {
        return new Retryer.Default(100, SECONDS.toMillis(1), 5);
    }
}

创建一个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

可以启动 eureka-server service-user client-feign 访问http://localhost:8765/user/hi?name=liajngbo
如果测试负载均衡功能可以多运行一个service-user用不同的端口8863,然后在浏览器刷新 http://localhost:8765/user/hi?name=liajngbo 会发现有不同的结果

Hi, my name is liajngbo, port: 8763
Hi, my name is liajngbo, port: 8863

client-feign项目中已经配置了hystrix,现在访问http://localhost:8765/hystrix

r1.png

在输入框中输入http://localhost:8765/hystrix.stream点击按扭

r2.png

Turbine项目 client-turbine-monitor

Turbine能够汇集监控信息,并将聚合后的信息提供给Hystrix Dashboard来集中展示和监控。
项目配置起来相当简单,只是2.0版本会有点小坑
pom.xml全部代码请参阅源码(源码包含了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>       

启动类:

@SpringBootApplication
@EnableTurbine
@EnableHystrixDashboard
public class ClientTurbineMonitorApplication {

    public static void main(String[] args) {
        SpringApplication.run(ClientTurbineMonitorApplication.class, args);
    }
}

@EnableTurbine 开启了turbine功能,@EnableHystrixDashboard开启了hystrix监控UI

一般的配置文件:

turbine:
  app-config: client-feign,client-order-ribbon,client-gateway-zuul # 指定了要监控的应用名字
  cluster-name-expression: new String("default") # 表示集群的名字为default
  combine-host-port: true # 表示同一主机上的服务通过host和port的组合来进行区分,默认情况下是使用host来区分,这样会使本地调试有问题

这里会有一个问题,turbine会去访问其它项目的/hystrix.stream路径,默认情况下turbine访问的是/actuator/hystrix.stream,这个路径访问不通,因为其它项目注册的路由地址是/hystrix.stream,所以要纠正turbine项目访问的默认地址,在配置文件中添加turbine.instanceUrlSuffix=hystrix.stream,management.context-path=/
配置文件:

management:
  context-path: /
turbine:
  app-config: client-feign,client-order-ribbon,client-gateway-zuul # 指定了要监控的应用名字
  cluster-name-expression: new String("default") # 表示集群的名字为default
  combine-host-port: true # 表示同一主机上的服务通过host和port的组合来进行区分,默认情况下是使用host来区分,这样会使本地调试有问题
  instanceUrlSuffix: hystrix.stream

测试一下turbine,必须启动多个项目 eureka-server、service-user、service-order、client-feign、client-order-ribbon、client-gateway-zuul、client-turbine-monitor
访问turbine之前要先访问一下其它项目,不然不会有数据显示turbine会处于loading中
访问 http://localhost:8767/turbine.stream 会有json格式的数据流

{"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}

访问hystrix UI http://localhost:8767/hystrix

e1.png

e2.png

网关Zuul client-gateway-zuul

项目依赖,完整的pom.xml中包含了其它的依赖

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

启动类:

@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
@EnableHystrixDashboard
public class ClientGatewayZuulApplication {

    public static void main(String[] args) {
        SpringApplication.run(ClientGatewayZuulApplication.class, args);
    }

    /**
     * springboot 版本如果是2.0则需要添加 ServletRegistrationBean
     * 因为springboot的默认路径不是 "/hystrix.stream",
     * 只要在自己的项目里配置上下面的servlet就可以了
     * 第一次访问hystrix.stream 会出现 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;
    }
}

开启网关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是路由规则,serviceId指定服务名称,prefix给路由加上前缀

注意:因为项目是我写好的demo,其中包含了hystrix功能,在/hystrix中Thread Pools会一直处于loading状态,这是由于Zuul默认会使用信号量来实现隔离,只有通过Hystrix配置把隔离机制改成为线程池的方式才能够得以展示,
SEMAPHORE - 它在调用线程上执行,并发请求受信号量计数的限制(Zuul默认此策略)
THREAD - 它在一个单独的线程上执行,并发请求受到线程池中线程数的限制
配置文件中添加

thread-pool:
    use-separate-thread-pools: true
  ribbon-isolation-strategy: thread # 每个路由使用独立的线程池

Zuul中提供Filter的作用有哪些,我觉得分为如下几点:

  • 网关是暴露在外面的,必须要进行权限控制
  • 可以针对服务做控制,在路由的时候处理,比如服务降级
  • 防止爬虫,利用Filter对请求进行过滤
  • 流量控制,只允许最高的并发量,保护后端的服务
  • 灰度发布,可以针对不用的用户进行路由来实现灰度

Filter种类

  • pre:可以在请求被路由之前调用
  • route:在路由请求时候被调用
  • post:在route和error过滤器之后被调用
  • error:处理请求时发生错误时被调用

zuul的Filter的生命周期,见下图:


2685774-66bb8fa036d4256a.png

创建一个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是决定这个过滤器需不需要执行,返回false则不执行,这个也可以利用配置中心来做,达到动态的开启关闭效果,
filterOrder是表示过滤器执行的顺序,数字越小,优先级越高
run里面就是我们自己要执行的业务逻辑,这里我们验证了一下接口参数中有没有token

zuul自身是集成了hystrix的,所以它带有熔断功能
创建一个ServiceUserFallbackProvider类实现接口FallbackProvider,实现service-user的熔断功能:

@Component
public class ServiceUserFallbackProvider implements FallbackProvider {

    static final Logger logger = LoggerFactory.getLogger(ServiceUserFallbackProvider.class);

    @Override
    public String getRoute() {
        // 表明是为哪个微服务提供回退,*表示为所有微服务提供回退,当前只为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;
            }
        };
    }
}

启动eureka-server、service-user、service-order、client-feign、client-order-ribbon、client-gateway-zuul,访问http://localhost:8771/v1/hiapi/user/say?name=liang&token=123
正常结果显示:

Hi, my name is liang, port: 8763

去掉token访问:http://localhost:8771/v1/hiapi/user/say?name=liang

token is empty

测试熔断效果,关停service-user项目 访问: http://localhost:8771/v1/hiapi/user/say?name=liang&token=123

oooops! error,i'm the fallback.

使用docker部署项目

Docker是一个用于开发、交付和运行应用的开放平台,Docker被设计用于更快地交付应用。Docker可以将应用程序和基础设施层隔离,并且可以将基础设施当作程序一样进行管理。使用Docker,可以更快地打包代码、测试以及部署,并且可以减少从编写到部署运行代码的周期。
Docker将内核容器特性(LXC)、工作流和工具集成,以帮助管理和部署应用。

什么是Docker
核心是,Docker是一种在安全隔离的容器中运行近乎所有应用的方式,这种隔离性和安全性允许你在同一个主机上同时运行多个容器,而容器的这种轻量级特性,无需消耗运行hpervisor所需的额外负载,意味着你可以节省更多的硬件资源。

docker如何安装这里不讲,自行解决

这里演示在单台宿主机上的测试结果

因为项目是我提前写好的项目,可以看到项目中的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 是开放的端口 多个端口可以以空格隔开 "8761 8762 8763"
ENTRYPOINT 是容器启动后执行的命令
springboot打包的项目jar的运行命令 "java -jar app.jar" 如果启用不同的配置文件的话要 “java -jar app.jar --spring.profiles.active=test”,所以上面定义了一个变量来接收容器启动设置的参数SPRING_PROFILES_ACTIVE 容器启动时加 -e "SPRING_PROFILES_ACTIVE=test"

maven 打包 docker 命令

mvn clean package docker:build -Dmaven.test.skip=true
# -Dmaven.test.skip 跳过单元测试

容器启动:

docker run -d -e "SPRING_PROFILES_ACTIVE=test-peer1" --name eureka-server -p 8761:8761 -it liangwang/eureka-server

同一台宿主机可以使用容器名称来通信 比如 eureka-server容器使用link参数将其它链接到容器2

docker run -d -e "SPRING_PROFILES_ACTIVE=test" --name service-user-01 --link=eureka-server -p 8763:8763 -it liangwang/service-user

对于注册与发现服务,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

下面可以按顺序打包项目:
项目根目录中有一个mvn-package-docker.sh

#!/bin/bash

echo "开始执行打包....[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 "执行打包结束.....[end]"

也可以手动打包各别你想打包的项目
打包完之后,执行命令 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之外都是打包生成的镜像
下面要运行容器来跑这些镜像,项目根目录有一个docker-start.sh脚本,里面是跑各个容器的命令,最好不要执行这个脚本,因为没有时间停顿,所以容器全部运行没有前后顺序,如果eureka-server没有跑起来,可能其它项目会报错,最好先手动一条一条执行,这里是演示测试所以没有用容器编排

# eureka-server docker 启动命令:
docker run -d -e "SPRING_PROFILES_ACTIVE=test-peer1" --name eureka-server -p 8761:8761 -it liangwang/eureka-server

# service-user-01 docker 启动命令:
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 启动命令:
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 启动命令:
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 启动命令:
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 启动命令:
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 启动命令:
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 启动命令:
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 启动命令:
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 启动命令:
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 启动命令:
docker run  -d -e "SPRING_PROFILES_ACTIVE=test" --name swagger-doc  --link=eureka-server -p 8772:8772 -it liangwang/swagger-doc

没有问题的情况下,执行docker ps能看到正在运行的容器进程

[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

这时候访问 http://localhost:8761,我项目部署在测试服务器所以我的访问地址为 http://172.16.10.177:8761/

e3.png

能看到项目都已经注册进来了

看admin-server 访问http://localhost:8773,我的访问地址为 http://172.16.10.177:8773

e5.png

e4.png

改造项目增加zipkin链路追踪

使用镜像运行zipkin项目

请先拉取镜像

docker pull openzipkin/zipkin
# 运行容器
# 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

在需要追踪的项目中添加依赖

    <!-- 链路追踪 zipkin -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-zipkin</artifactId>
    </dependency>

在application.yml中添加

spring:
  zipkin:
    base-url: http://localhost:9411 # 如果zipkin服务在其它服务器,localhost应为对应的IP
  sleuth:
    sampler:
      probability: 1.0

sleuth.sampler.probability 是监控的百分比,默认的是0.1表示10%,这里给1.0表示全部监控
spring.zipkin.base-url:是zipkin-server的服务路径

访问 http://localhost:9411

e7.png
e6.png
e8.png

后续我会集成OAuth2.0 JWT和Config配置中心

Docker Swarm 搭建SpringCloud集群

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容