├── .gitignore ├── README.md ├── auth-service ├── Dockerfile ├── pom.xml └── src │ └── main │ ├── java │ └── cn │ │ └── zhangxd │ │ └── auth │ │ ├── AuthApplication.java │ │ ├── config │ │ ├── OAuthConfiguration.java │ │ └── ResourceServerConfiguration.java │ │ └── controller │ │ └── UserController.java │ └── resources │ ├── bootstrap.yml │ ├── logback-spring.xml │ └── schema.sql ├── config-repo ├── application.yml ├── auth-service.yml ├── gateway.yml ├── svca-service.yml └── svcb-service.yml ├── config ├── Dockerfile ├── pom.xml └── src │ ├── main │ ├── java │ │ └── cn │ │ │ └── zhangxd │ │ │ └── config │ │ │ └── ConfigApplication.java │ └── resources │ │ ├── application.yml │ │ └── bootstrap.yml │ └── test │ └── java │ └── cn │ └── zhangxd │ └── config │ └── ApplicationTests.java ├── docker-compose.yml ├── gateway ├── Dockerfile ├── pom.xml └── src │ └── main │ ├── java │ └── cn │ │ └── zhangxd │ │ └── gateway │ │ └── GatewayApplication.java │ └── resources │ ├── bootstrap.yml │ └── logback-spring.xml ├── monitor ├── Dockerfile ├── pom.xml └── src │ └── main │ ├── java │ └── cn │ │ └── zhangxd │ │ └── monitor │ │ └── MonitorApplication.java │ └── resources │ ├── application.yml │ ├── bootstrap.yml │ └── logback-spring.xml ├── pom.xml ├── registry ├── Dockerfile ├── pom.xml └── src │ ├── main │ ├── java │ │ └── cn │ │ │ └── zhangxd │ │ │ └── registry │ │ │ └── RegistryApplication.java │ └── resources │ │ ├── application.yml │ │ └── bootstrap.yml │ └── test │ └── java │ └── cn │ └── zhangxd │ └── registry │ └── ApplicationTests.java ├── screenshots ├── architecture.jpg ├── components.jpg ├── monitor1.jpg ├── monitor10.jpg ├── monitor11.jpg ├── monitor12.jpg ├── monitor2.jpg ├── monitor3.jpg ├── monitor4.jpg ├── monitor5.jpg ├── monitor6.jpg ├── monitor7.jpg ├── monitor8.jpg ├── monitor9.jpg ├── rabbit.jpg ├── registry.jpg ├── zipkin1.jpg ├── zipkin2.jpg └── zipkin3.jpg ├── svca-service ├── Dockerfile ├── pom.xml └── src │ └── main │ ├── java │ └── cn │ │ └── zhangxd │ │ └── svca │ │ ├── ServiceAApplication.java │ │ ├── client │ │ └── ServiceBClient.java │ │ ├── config │ │ └── ServiceAConfiguration.java │ │ └── controller │ │ └── ServiceAController.java │ └── resources │ ├── bootstrap.yml │ └── logback-spring.xml ├── svcb-service ├── Dockerfile ├── pom.xml └── src │ └── main │ ├── java │ └── cn │ │ └── zhangxd │ │ └── svcb │ │ ├── ServiceBApplication.java │ │ ├── config │ │ └── ServiceBConfiguration.java │ │ └── controller │ │ └── ServiceBController.java │ └── resources │ ├── bootstrap.yml │ └── logback-spring.xml └── zipkin ├── Dockerfile ├── pom.xml └── src └── main ├── java └── cn │ └── zhangxd │ └── zipkin │ └── ZipkinApplication.java └── resources └── application.yml /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea/ 3 | *.iml 4 | target/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 基于 Spring Cloud 的微服务架构 2 | 3 | 本项目是一个基于 Spring Boot、Spring Cloud、Spring Oauth2 和 Spring Cloud Netflix 等框架构建的微服务项目。 4 | 5 | # 技术栈 6 | * Spring boot - 微服务的入门级微框架,用来简化 Spring 应用的初始搭建以及开发过程。 7 | * Eureka - 云端服务发现,一个基于 REST 的服务,用于定位服务,以实现云端中间层服务发现和故障转移。 8 | * Spring Cloud Config - 配置管理工具包,让你可以把配置放到远程服务器,集中化管理集群配置,目前支持本地存储、Git 以及 Subversion。 9 | * Hystrix - 熔断器,容错管理工具,旨在通过熔断机制控制服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。 10 | * Zuul - Zuul 是在云平台上提供动态路由,监控,弹性,安全等边缘服务的框架。Zuul 相当于是设备和 Netflix 流应用的 Web 网站后端所有请求的前门。 11 | * Spring Cloud Bus - 事件、消息总线,用于在集群(例如,配置变化事件)中传播状态变化,可与 Spring Cloud Config 联合实现热部署。 12 | * Spring Cloud Sleuth - 日志收集工具包,封装了 Dapper 和 log-based 追踪以及 Zipkin 和 HTrace 操作,为 SpringCloud 应用实现了一种分布式追踪解决方案。 13 | * Ribbon - 提供云端负载均衡,有多种负载均衡策略可供选择,可配合服务发现和断路器使用。 14 | * Turbine - Turbine 是聚合服务器发送事件流数据的一个工具,用来监控集群下 hystrix 的 metrics 情况。 15 | * Spring Cloud Stream - Spring 数据流操作开发包,封装了与 Redis、Rabbit、Kafka 等发送接收消息。 16 | * Feign - Feign 是一种声明式、模板化的 HTTP 客户端。 17 | * Spring Cloud OAuth2 - 基于 Spring Security 和 OAuth2 的安全工具包,为你的应用程序添加安全控制。 18 | 19 | # 应用架构 20 | 21 | 该项目包含 8 个服务 22 | 23 | * registry - 服务注册与发现 24 | * config - 外部配置 25 | * monitor - 监控 26 | * zipkin - 分布式跟踪 27 | * gateway - 代理所有微服务的接口网关 28 | * auth-service - OAuth2 认证服务 29 | * svca-service - 业务服务A 30 | * svcb-service - 业务服务B 31 | 32 | ## 体系架构 33 | ![architecture](/screenshots/architecture.jpg) 34 | ## 应用组件 35 | ![components](/screenshots/components.jpg) 36 | 37 | # 启动项目 38 | 39 | * 使用 Docker 快速启动 40 | 1. 配置 Docker 环境 41 | 2. `mvn clean package` 打包项目及 Docker 镜像 42 | 3. 在项目根目录下执行 `docker-compose up -d` 启动所有项目 43 | * 本地手动启动 44 | 1. 配置 rabbitmq 45 | 2. 修改 hosts 将主机名指向到本地 46 | `127.0.0.1 registry config monitor rabbitmq auth-service` 47 | 或者修改各服务配置文件中的相应主机名为本地 ip 48 | 3. 启动 registry、config、monitor、zipkin 49 | 4. 启动 gateway、auth-service、svca-service、svcb-service 50 | 51 | # 项目预览 52 | 53 | ## 注册中心 54 | 访问 http://localhost:8761/ 默认账号 user,密码 password 55 | 56 | ![registry](/screenshots/registry.jpg) 57 | ## 监控 58 | 访问 http://localhost:8040/ 默认账号 admin,密码 admin 59 | ### 控制面板 60 | ![monitor](/screenshots/monitor1.jpg) 61 | ### 应用注册历史 62 | ![monitor](/screenshots/monitor2.jpg) 63 | ### Turbine Hystrix面板 64 | ![monitor](/screenshots/monitor3.jpg) 65 | ### 应用信息、健康状况、垃圾回收等详情 66 | ![monitor](/screenshots/monitor4.jpg) 67 | ### 计数器 68 | ![monitor](/screenshots/monitor5.jpg) 69 | ### 查看和修改环境变量 70 | ![monitor](/screenshots/monitor6.jpg) 71 | ### 管理 Logback 日志级别 72 | ![monitor](/screenshots/monitor7.jpg) 73 | ### 查看并使用 JMX 74 | ![monitor](/screenshots/monitor8.jpg) 75 | ### 查看线程 76 | ![monitor](/screenshots/monitor9.jpg) 77 | ### 认证历史 78 | ![monitor](/screenshots/monitor10.jpg) 79 | ### 查看 Http 请求轨迹 80 | ![monitor](/screenshots/monitor11.jpg) 81 | ### Hystrix 面板 82 | ![monitor](/screenshots/monitor12.jpg) 83 | ## 链路跟踪 84 | 访问 http://localhost:9411/ 默认账号 admin,密码 admin 85 | ### 控制面板 86 | ![zipkin](/screenshots/zipkin1.jpg) 87 | ### 链路跟踪明细 88 | ![zipkin](/screenshots/zipkin2.jpg) 89 | ### 服务依赖关系 90 | ![zipkin](/screenshots/zipkin3.jpg) 91 | ## RabbitMQ 监控 92 | Docker 启动访问 http://localhost:15673/ 默认账号 guest,密码 guest(本地 rabbit 管理系统默认端口15672) 93 | 94 | ![rabbit](/screenshots/rabbit.jpg) 95 | # 接口测试 96 | 1. 获取 Token 97 | ``` 98 | curl -X POST -vu client:secret http://localhost:8060/uaa/oauth/token -H "Accept: application/json" -d "password=password&username=anil&grant_type=password&scope=read%20write" 99 | ``` 100 | 返回如下格式数据: 101 | ``` 102 | { 103 | "access_token": "eac56504-c4f0-4706-b72e-3dc3acdf45e9", 104 | "token_type": "bearer", 105 | "refresh_token": "da1007dc-683c-4309-965d-370b15aa4aeb", 106 | "expires_in": 3599, 107 | "scope": "read write" 108 | } 109 | ``` 110 | 2. 使用 access token 访问 service a 接口 111 | ``` 112 | curl -i -H "Authorization: Bearer eac56504-c4f0-4706-b72e-3dc3acdf45e9" http://localhost:8060/svca 113 | ``` 114 | 返回如下数据: 115 | ``` 116 | svca-service (172.18.0.8:8080)===>name:zhangxd 117 | svcb-service (172.18.0.2:8070)===>Say Hello 118 | ``` 119 | 3. 使用 access token 访问 service b 接口 120 | ``` 121 | curl -i -H "Authorization: Bearer eac56504-c4f0-4706-b72e-3dc3acdf45e9" http://localhost:8060/svcb 122 | ``` 123 | 返回如下数据: 124 | ``` 125 | svcb-service (172.18.0.2:8070)===>Say Hello 126 | ``` 127 | 4. 使用 refresh token 刷新 token 128 | ``` 129 | curl -X POST -vu client:secret http://localhost:8060/uaa/oauth/token -H "Accept: application/json" -d "grant_type=refresh_token&refresh_token=da1007dc-683c-4309-965d-370b15aa4aeb" 130 | ``` 131 | 返回更新后的 Token: 132 | ``` 133 | { 134 | "access_token": "63ff57ce-f140-482e-ba7e-b6f29df35c88", 135 | "token_type": "bearer", 136 | "refresh_token": "da1007dc-683c-4309-965d-370b15aa4aeb", 137 | "expires_in": 3599, 138 | "scope": "read write" 139 | } 140 | ``` 141 | 5. 刷新配置 142 | ``` 143 | curl -X POST -vu user:password http://localhost:8888/bus/refresh 144 | ``` -------------------------------------------------------------------------------- /auth-service/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM java:8 2 | VOLUME /tmp 3 | ADD ./target/auth-service.jar /app.jar 4 | RUN bash -c 'touch /app.jar' 5 | EXPOSE 5000 6 | ENTRYPOINT ["java","-jar","/app.jar"] -------------------------------------------------------------------------------- /auth-service/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | cn.zhangxd 9 | spring-boot-cloud 10 | 1.0-SNAPSHOT 11 | 12 | 13 | auth-service 14 | 1.0-SNAPSHOT 15 | jar 16 | ${project.artifactId} 17 | 18 | 19 | 20 | org.springframework.boot 21 | spring-boot-starter-data-jpa 22 | 23 | 24 | com.h2database 25 | h2 26 | runtime 27 | 28 | 29 | 30 | org.springframework.cloud 31 | spring-cloud-starter-oauth2 32 | 33 | 34 | 35 | org.springframework.cloud 36 | spring-cloud-starter-eureka 37 | 38 | 39 | 40 | org.springframework.cloud 41 | spring-cloud-starter-sleuth 42 | 43 | 44 | org.springframework.cloud 45 | spring-cloud-sleuth-stream 46 | 47 | 48 | org.springframework.cloud 49 | spring-cloud-stream-binder-rabbit 50 | 51 | 52 | 53 | org.springframework.cloud 54 | spring-cloud-starter-config 55 | 56 | 57 | org.springframework.cloud 58 | spring-cloud-starter-bus-amqp 59 | 60 | 61 | org.springframework.cloud 62 | spring-cloud-starter-hystrix 63 | 64 | 65 | org.springframework.cloud 66 | spring-cloud-netflix-hystrix-stream 67 | 68 | 69 | org.springframework.cloud 70 | spring-cloud-starter-ribbon 71 | 72 | 73 | org.springframework.boot 74 | spring-boot-starter-aop 75 | 76 | 77 | org.springframework.retry 78 | spring-retry 79 | 80 | 81 | org.jolokia 82 | jolokia-core 83 | 84 | 85 | 86 | 87 | ${project.artifactId} 88 | 89 | 90 | org.springframework.boot 91 | spring-boot-maven-plugin 92 | 93 | 94 | com.spotify 95 | docker-maven-plugin 96 | 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /auth-service/src/main/java/cn/zhangxd/auth/AuthApplication.java: -------------------------------------------------------------------------------- 1 | package cn.zhangxd.auth; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 6 | 7 | @SpringBootApplication 8 | @EnableDiscoveryClient 9 | public class AuthApplication { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(AuthApplication.class, args); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /auth-service/src/main/java/cn/zhangxd/auth/config/OAuthConfiguration.java: -------------------------------------------------------------------------------- 1 | package cn.zhangxd.auth.config; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.core.annotation.Order; 7 | import org.springframework.security.authentication.AuthenticationManager; 8 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 9 | import org.springframework.security.config.annotation.authentication.configurers.GlobalAuthenticationConfigurerAdapter; 10 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 11 | import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; 12 | import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; 13 | import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; 14 | import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; 15 | import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer; 16 | import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore; 17 | 18 | import javax.sql.DataSource; 19 | 20 | @Configuration 21 | @EnableAuthorizationServer 22 | public class OAuthConfiguration extends AuthorizationServerConfigurerAdapter { 23 | 24 | @Autowired 25 | private AuthenticationManager auth; 26 | 27 | @Autowired 28 | private DataSource dataSource; 29 | 30 | private BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); 31 | 32 | @Bean 33 | public JdbcTokenStore tokenStore() { 34 | return new JdbcTokenStore(dataSource); 35 | } 36 | 37 | @Override 38 | public void configure(AuthorizationServerSecurityConfigurer security) 39 | throws Exception { 40 | security.passwordEncoder(passwordEncoder); 41 | } 42 | 43 | @Override 44 | public void configure(AuthorizationServerEndpointsConfigurer endpoints) 45 | throws Exception { 46 | endpoints 47 | .authenticationManager(auth) 48 | .tokenStore(tokenStore()) 49 | ; 50 | } 51 | 52 | @Override 53 | public void configure(ClientDetailsServiceConfigurer clients) 54 | throws Exception { 55 | 56 | clients.jdbc(dataSource) 57 | .passwordEncoder(passwordEncoder) 58 | .withClient("client") 59 | .secret("secret") 60 | .authorizedGrantTypes("password", "refresh_token") 61 | .scopes("read", "write") 62 | .accessTokenValiditySeconds(3600) // 1 hour 63 | .refreshTokenValiditySeconds(2592000) // 30 days 64 | .and() 65 | .withClient("svca-service") 66 | .secret("password") 67 | .authorizedGrantTypes("client_credentials", "refresh_token") 68 | .scopes("server") 69 | .and() 70 | .withClient("svcb-service") 71 | .secret("password") 72 | .authorizedGrantTypes("client_credentials", "refresh_token") 73 | .scopes("server") 74 | ; 75 | 76 | } 77 | 78 | @Configuration 79 | @Order(-20) 80 | protected static class AuthenticationManagerConfiguration extends GlobalAuthenticationConfigurerAdapter { 81 | 82 | @Autowired 83 | private DataSource dataSource; 84 | 85 | @Override 86 | public void init(AuthenticationManagerBuilder auth) throws Exception { 87 | auth.jdbcAuthentication().dataSource(dataSource) 88 | .withUser("dave").password("secret").roles("USER") 89 | .and() 90 | .withUser("anil").password("password").roles("ADMIN") 91 | ; 92 | } 93 | } 94 | 95 | } -------------------------------------------------------------------------------- /auth-service/src/main/java/cn/zhangxd/auth/config/ResourceServerConfiguration.java: -------------------------------------------------------------------------------- 1 | package cn.zhangxd.auth.config; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 5 | import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; 6 | import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; 7 | 8 | @Configuration 9 | @EnableResourceServer 10 | public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter { 11 | 12 | @Override 13 | public void configure(HttpSecurity http) throws Exception { 14 | http 15 | .requestMatchers().antMatchers("/current") 16 | .and() 17 | .authorizeRequests() 18 | .antMatchers("/current").access("#oauth2.hasScope('read')"); 19 | } 20 | } -------------------------------------------------------------------------------- /auth-service/src/main/java/cn/zhangxd/auth/controller/UserController.java: -------------------------------------------------------------------------------- 1 | package cn.zhangxd.auth.controller; 2 | 3 | import org.springframework.web.bind.annotation.GetMapping; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | import org.springframework.web.bind.annotation.RestController; 6 | 7 | import java.security.Principal; 8 | 9 | @RestController 10 | @RequestMapping("/") 11 | public class UserController { 12 | 13 | @GetMapping(value = "/current") 14 | public Principal getUser(Principal principal) { 15 | return principal; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /auth-service/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: auth-service 4 | cloud: 5 | config: 6 | uri: http://config:8888 7 | fail-fast: true 8 | username: user 9 | password: ${CONFIG_SERVER_PASSWORD:password} 10 | retry: 11 | initial-interval: 2000 12 | max-interval: 10000 13 | multiplier: 2 14 | max-attempts: 10 15 | -------------------------------------------------------------------------------- /auth-service/src/main/resources/logback-spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /auth-service/src/main/resources/schema.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE IF EXISTS `oauth_access_token`; 2 | CREATE TABLE `oauth_access_token` ( 3 | `token_id` varchar(256) DEFAULT NULL, 4 | `token` blob, 5 | `authentication_id` varchar(256) DEFAULT NULL, 6 | `user_name` varchar(256) DEFAULT NULL, 7 | `client_id` varchar(256) DEFAULT NULL, 8 | `authentication` blob, 9 | `refresh_token` varchar(256) DEFAULT NULL 10 | ); 11 | 12 | DROP TABLE IF EXISTS `oauth_client_details`; 13 | CREATE TABLE `oauth_client_details` ( 14 | `client_id` varchar(256) NOT NULL, 15 | `resource_ids` varchar(256) DEFAULT NULL, 16 | `client_secret` varchar(256) DEFAULT NULL, 17 | `scope` varchar(256) DEFAULT NULL, 18 | `authorized_grant_types` varchar(256) DEFAULT NULL, 19 | `web_server_redirect_uri` varchar(256) DEFAULT NULL, 20 | `authorities` varchar(256) DEFAULT NULL, 21 | `access_token_validity` int(11) DEFAULT NULL, 22 | `refresh_token_validity` int(11) DEFAULT NULL, 23 | `additional_information` varchar(4096) DEFAULT NULL, 24 | `autoapprove` varchar(256) DEFAULT NULL, 25 | PRIMARY KEY (`client_id`) 26 | ); 27 | 28 | DROP TABLE IF EXISTS `oauth_refresh_token`; 29 | CREATE TABLE `oauth_refresh_token` ( 30 | `token_id` varchar(256) DEFAULT NULL, 31 | `token` blob, 32 | `authentication` blob 33 | ); 34 | 35 | DROP TABLE IF EXISTS `users`; 36 | CREATE TABLE `users` ( 37 | `username` varchar(50) NOT NULL, 38 | `password` varchar(50) NOT NULL, 39 | `enabled` tinyint(1) NOT NULL, 40 | PRIMARY KEY (`username`) 41 | ); 42 | 43 | DROP TABLE IF EXISTS `authorities`; 44 | CREATE TABLE `authorities` ( 45 | `username` varchar(50) NOT NULL, 46 | `authority` varchar(50) NOT NULL, 47 | UNIQUE KEY `ix_auth_username` (`username`,`authority`) 48 | ); -------------------------------------------------------------------------------- /config-repo/application.yml: -------------------------------------------------------------------------------- 1 | eureka: 2 | instance: 3 | hostname: registry 4 | prefer-ip-address: true 5 | client: 6 | service-url: 7 | defaultZone: http://user:${REGISTRY_SERVER_PASSWORD:password}@registry:8761/eureka/ 8 | 9 | hystrix: 10 | command: 11 | default: 12 | execution: 13 | isolation: 14 | thread: 15 | timeoutInMilliseconds: 10000 16 | 17 | ribbon: 18 | ReadTimeout: 5000 19 | ConnectTimeout: 5000 20 | 21 | spring: 22 | rabbitmq: 23 | host: rabbitmq 24 | sleuth: 25 | sampler: 26 | percentage: 1 27 | integration: 28 | enabled: false 29 | scheduled: 30 | skip-pattern: "^org.*HystrixStreamTask$" 31 | 32 | authserver: 33 | hostname: auth-service 34 | port: 5000 35 | contextPath: /uaa 36 | 37 | security: 38 | oauth2: 39 | resource: 40 | user-info-uri: http://${authserver.hostname}:${authserver.port}${authserver.contextPath}/current -------------------------------------------------------------------------------- /config-repo/auth-service.yml: -------------------------------------------------------------------------------- 1 | server: 2 | context-path: /uaa 3 | port: 5000 4 | 5 | management: 6 | security: 7 | enabled: false 8 | context-path: /mgmt 9 | 10 | eureka: 11 | instance: 12 | health-check-url-path: ${server.context-path}${management.context-path}/health 13 | status-page-url-path: ${server.context-path}${management.context-path}/info 14 | metadata-map: 15 | management.context-path: ${server.context-path}${management.context-path} 16 | 17 | spring: 18 | datasource: 19 | url: jdbc:h2:mem:user 20 | driver-class-name: org.h2.Driver 21 | jpa: 22 | show-sql: true 23 | -------------------------------------------------------------------------------- /config-repo/gateway.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8060 3 | 4 | management: 5 | security: 6 | enabled: false 7 | 8 | hystrix: 9 | command: 10 | default: 11 | execution: 12 | isolation: 13 | thread: 14 | timeoutInMilliseconds: 20000 15 | 16 | ribbon: 17 | ReadTimeout: 10000 18 | ConnectTimeout: 10000 19 | 20 | zuul: 21 | ignoredServices: '*' 22 | routes: 23 | auth-service: 24 | path: /uaa/** 25 | stripPrefix: false 26 | sensitiveHeaders: 27 | svca-service: 28 | path: /svca/** 29 | sensitiveHeaders: 30 | svcb-service: 31 | path: /svcb/** 32 | sensitiveHeaders: -------------------------------------------------------------------------------- /config-repo/svca-service.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8080 3 | 4 | name: zhangxd 5 | 6 | eureka: 7 | instance: 8 | metadata-map: 9 | user.name: ${security.user.name} 10 | user.password: ${security.user.password} 11 | 12 | security: 13 | user: 14 | name: user 15 | password: password 16 | oauth2: 17 | client: 18 | clientId: svca-service 19 | clientSecret: ${security.user.password} 20 | accessTokenUri: http://${authserver.hostname}:${authserver.port}${authserver.contextPath}/oauth/token 21 | grant-type: client_credentials 22 | scope: server -------------------------------------------------------------------------------- /config-repo/svcb-service.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8070 3 | 4 | msg: Hello 5 | 6 | eureka: 7 | instance: 8 | metadata-map: 9 | user.name: ${security.user.name} 10 | user.password: ${security.user.password} 11 | 12 | security: 13 | user: 14 | name: user 15 | password: password 16 | oauth2: 17 | client: 18 | clientId: svcb-service 19 | clientSecret: ${security.user.password} 20 | accessTokenUri: http://${authserver.hostname}:${authserver.port}${authserver.contextPath}/oauth/token 21 | grant-type: client_credentials 22 | scope: server -------------------------------------------------------------------------------- /config/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM java:8 2 | VOLUME /tmp 3 | ADD ./target/config.jar /app.jar 4 | RUN bash -c 'touch /app.jar' 5 | EXPOSE 8888 6 | ENTRYPOINT ["java","-jar","/app.jar"] -------------------------------------------------------------------------------- /config/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | cn.zhangxd 9 | spring-boot-cloud 10 | 1.0-SNAPSHOT 11 | 12 | 13 | config 14 | 1.0-SNAPSHOT 15 | jar 16 | ${project.artifactId} 17 | 18 | 19 | 20 | org.springframework.cloud 21 | spring-cloud-config-server 22 | 23 | 24 | org.springframework.cloud 25 | spring-cloud-config-monitor 26 | 27 | 28 | org.springframework.cloud 29 | spring-cloud-starter-stream-rabbit 30 | 31 | 32 | org.springframework.cloud 33 | spring-cloud-starter-eureka 34 | 35 | 36 | org.springframework.boot 37 | spring-boot-starter-security 38 | 39 | 40 | 41 | 42 | ${project.artifactId} 43 | 44 | 45 | org.springframework.boot 46 | spring-boot-maven-plugin 47 | 48 | 49 | com.spotify 50 | docker-maven-plugin 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /config/src/main/java/cn/zhangxd/config/ConfigApplication.java: -------------------------------------------------------------------------------- 1 | package cn.zhangxd.config; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 6 | import org.springframework.cloud.config.server.EnableConfigServer; 7 | 8 | @EnableDiscoveryClient 9 | @EnableConfigServer 10 | @SpringBootApplication 11 | public class ConfigApplication { 12 | 13 | public static void main(String[] args) { 14 | SpringApplication.run(ConfigApplication.class, args); 15 | } 16 | 17 | } -------------------------------------------------------------------------------- /config/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8888 3 | 4 | eureka: 5 | instance: 6 | hostname: registry 7 | prefer-ip-address: true 8 | metadata-map: 9 | user.name: ${security.user.name} 10 | user.password: ${security.user.password} 11 | client: 12 | service-url: 13 | defaultZone: http://user:${REGISTRY_SERVER_PASSWORD:password}@registry:8761/eureka/ 14 | 15 | spring: 16 | cloud: 17 | config: 18 | server: 19 | git: 20 | uri: https://github.com/zhangxd1989/spring-boot-cloud 21 | search-paths: config-repo 22 | rabbitmq: 23 | host: rabbitmq 24 | 25 | security: 26 | user: 27 | name: user 28 | password: ${CONFIG_SERVER_PASSWORD:password} 29 | -------------------------------------------------------------------------------- /config/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: config -------------------------------------------------------------------------------- /config/src/test/java/cn/zhangxd/config/ApplicationTests.java: -------------------------------------------------------------------------------- 1 | package cn.zhangxd.config; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.beans.factory.annotation.Value; 7 | import org.springframework.boot.test.context.SpringBootTest; 8 | import org.springframework.boot.test.web.client.TestRestTemplate; 9 | import org.springframework.http.HttpStatus; 10 | import org.springframework.http.ResponseEntity; 11 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 12 | import org.springframework.util.LinkedMultiValueMap; 13 | import org.springframework.util.MultiValueMap; 14 | 15 | import java.util.Map; 16 | 17 | import static org.junit.Assert.assertEquals; 18 | import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; 19 | 20 | @RunWith(SpringJUnit4ClassRunner.class) 21 | @SpringBootTest(webEnvironment = RANDOM_PORT) 22 | public class ApplicationTests { 23 | 24 | @Autowired 25 | private TestRestTemplate testRestTemplate; 26 | @Value("${security.user.name}") 27 | private String username; 28 | @Value("${security.user.password}") 29 | private String password; 30 | 31 | @Test 32 | public void configurationAvailable() { 33 | @SuppressWarnings("rawtypes") 34 | ResponseEntity entity = 35 | testRestTemplate 36 | .withBasicAuth(username, password) 37 | .getForEntity("/app/cloud", Map.class); 38 | assertEquals(HttpStatus.OK, entity.getStatusCode()); 39 | } 40 | 41 | @Test 42 | public void envPostAvailable() { 43 | MultiValueMap form = new LinkedMultiValueMap(); 44 | @SuppressWarnings("rawtypes") 45 | ResponseEntity entity = 46 | testRestTemplate 47 | .withBasicAuth(username, password) 48 | .postForEntity("/admin/env", form, Map.class); 49 | assertEquals(HttpStatus.OK, entity.getStatusCode()); 50 | } 51 | 52 | } -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | rabbitmq: 4 | image: rabbitmq:3-management 5 | restart: always 6 | ports: 7 | - 15673:15672 8 | registry: 9 | image: spring-boot-cloud/registry 10 | ports: 11 | - "8761:8761" 12 | config: 13 | image: spring-boot-cloud/config 14 | ports: 15 | - "8888:8888" 16 | monitor: 17 | image: spring-boot-cloud/monitor 18 | ports: 19 | - "8040:8040" 20 | zipkin: 21 | image: spring-boot-cloud/zipkin 22 | ports: 23 | - "9411:9411" 24 | gateway: 25 | image: spring-boot-cloud/gateway 26 | ports: 27 | - "8060:8060" 28 | auth-service: 29 | image: spring-boot-cloud/auth-service 30 | ports: 31 | - "5000:5000" 32 | svca-service: 33 | image: spring-boot-cloud/svca-service 34 | svcb-service: 35 | image: spring-boot-cloud/svcb-service -------------------------------------------------------------------------------- /gateway/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM java:8 2 | VOLUME /tmp 3 | ADD ./target/gateway.jar /app.jar 4 | RUN bash -c 'touch /app.jar' 5 | EXPOSE 8060 6 | ENTRYPOINT ["java","-jar","/app.jar"] -------------------------------------------------------------------------------- /gateway/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | cn.zhangxd 9 | spring-boot-cloud 10 | 1.0-SNAPSHOT 11 | 12 | 13 | gateway 14 | 1.0-SNAPSHOT 15 | jar 16 | ${project.artifactId} 17 | 18 | 19 | 20 | org.springframework.cloud 21 | spring-cloud-starter-zuul 22 | 23 | 24 | org.springframework.cloud 25 | spring-cloud-starter-config 26 | 27 | 28 | org.springframework.cloud 29 | spring-cloud-starter-eureka 30 | 31 | 32 | org.springframework.cloud 33 | spring-cloud-starter-bus-amqp 34 | 35 | 36 | org.springframework.cloud 37 | spring-cloud-netflix-hystrix-stream 38 | 39 | 40 | org.springframework.cloud 41 | spring-cloud-starter-sleuth 42 | 43 | 44 | org.springframework.cloud 45 | spring-cloud-sleuth-stream 46 | 47 | 48 | org.springframework.cloud 49 | spring-cloud-stream-binder-rabbit 50 | 51 | 52 | org.springframework.boot 53 | spring-boot-starter-aop 54 | 55 | 56 | org.springframework.retry 57 | spring-retry 58 | 59 | 60 | org.jolokia 61 | jolokia-core 62 | 63 | 64 | 65 | 66 | ${project.artifactId} 67 | 68 | 69 | org.springframework.boot 70 | spring-boot-maven-plugin 71 | 72 | 73 | com.spotify 74 | docker-maven-plugin 75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /gateway/src/main/java/cn/zhangxd/gateway/GatewayApplication.java: -------------------------------------------------------------------------------- 1 | package cn.zhangxd.gateway; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 6 | import org.springframework.cloud.netflix.zuul.EnableZuulProxy; 7 | 8 | @SpringBootApplication 9 | @EnableDiscoveryClient 10 | @EnableZuulProxy 11 | public class GatewayApplication { 12 | 13 | public static void main(String[] args) { 14 | SpringApplication.run(GatewayApplication.class, args); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /gateway/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: gateway 4 | cloud: 5 | config: 6 | uri: http://config:8888 7 | fail-fast: true 8 | username: user 9 | password: ${CONFIG_SERVER_PASSWORD:password} 10 | retry: 11 | initial-interval: 2000 12 | max-interval: 10000 13 | multiplier: 2 14 | max-attempts: 10 15 | -------------------------------------------------------------------------------- /gateway/src/main/resources/logback-spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /monitor/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM java:8 2 | VOLUME /tmp 3 | ADD ./target/monitor.jar /app.jar 4 | RUN bash -c 'touch /app.jar' 5 | EXPOSE 8040 8041 6 | ENTRYPOINT ["java","-jar","/app.jar"] -------------------------------------------------------------------------------- /monitor/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | cn.zhangxd 9 | spring-boot-cloud 10 | 1.0-SNAPSHOT 11 | 12 | 13 | monitor 14 | 1.0-SNAPSHOT 15 | jar 16 | ${project.artifactId} 17 | 18 | 19 | 20 | de.codecentric 21 | spring-boot-admin-server 22 | 23 | 24 | de.codecentric 25 | spring-boot-admin-server-ui 26 | 27 | 28 | de.codecentric 29 | spring-boot-admin-server-ui-login 30 | 31 | 32 | de.codecentric 33 | spring-boot-admin-server-ui-hystrix 34 | 35 | 36 | de.codecentric 37 | spring-boot-admin-server-ui-turbine 38 | 39 | 40 | org.springframework.cloud 41 | spring-cloud-starter-turbine-stream 42 | 43 | 44 | netty-transport-native-epoll 45 | io.netty 46 | 47 | 48 | netty-codec-http 49 | io.netty 50 | 51 | 52 | 53 | 54 | org.springframework.cloud 55 | spring-cloud-starter-stream-rabbit 56 | 57 | 58 | org.springframework.cloud 59 | spring-cloud-starter-eureka 60 | 61 | 62 | org.springframework.boot 63 | spring-boot-starter-security 64 | 65 | 66 | 67 | 68 | ${project.artifactId} 69 | 70 | 71 | org.springframework.boot 72 | spring-boot-maven-plugin 73 | 74 | 75 | com.spotify 76 | docker-maven-plugin 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /monitor/src/main/java/cn/zhangxd/monitor/MonitorApplication.java: -------------------------------------------------------------------------------- 1 | package cn.zhangxd.monitor; 2 | 3 | import de.codecentric.boot.admin.config.EnableAdminServer; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 7 | import org.springframework.cloud.netflix.turbine.stream.EnableTurbineStream; 8 | import org.springframework.context.annotation.Configuration; 9 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 10 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 11 | 12 | @SpringBootApplication 13 | @EnableDiscoveryClient 14 | @EnableAdminServer 15 | @EnableTurbineStream 16 | public class MonitorApplication { 17 | 18 | public static void main(String[] args) { 19 | SpringApplication.run(MonitorApplication.class, args); 20 | } 21 | 22 | @Configuration 23 | public static class SecurityConfig extends WebSecurityConfigurerAdapter { 24 | @Override 25 | protected void configure(HttpSecurity http) throws Exception { 26 | // Page with login form is served as /login.html and does a POST on /login 27 | http.formLogin().loginPage("/login.html").loginProcessingUrl("/login").permitAll(); 28 | // The UI does a POST on /logout on logout 29 | http.logout().logoutUrl("/logout"); 30 | // The ui currently doesn't support csrf 31 | http.csrf().disable(); 32 | 33 | // Requests for the login page and the static assets are allowed 34 | http.authorizeRequests() 35 | .antMatchers("/login.html", "/**/*.css", "/img/**", "/third-party/**") 36 | .permitAll(); 37 | // ... and any other request needs to be authorized 38 | http.authorizeRequests().antMatchers("/**").authenticated(); 39 | 40 | // Enable so that the clients can authenticate via HTTP basic for registering 41 | http.httpBasic(); 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /monitor/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | logging: 2 | level: 3 | org.springframework.cloud.netflix.zuul.filters.post.SendErrorFilter: error 4 | 5 | server: 6 | port: 8040 7 | 8 | turbine: 9 | stream: 10 | port: 8041 11 | 12 | eureka: 13 | instance: 14 | hostname: registry 15 | prefer-ip-address: true 16 | metadata-map: 17 | user.name: ${security.user.name} 18 | user.password: ${security.user.password} 19 | client: 20 | service-url: 21 | defaultZone: http://user:${REGISTRY_SERVER_PASSWORD:password}@registry:8761/eureka/ 22 | 23 | spring: 24 | rabbitmq: 25 | host: rabbitmq 26 | boot: 27 | admin: 28 | routes: 29 | endpoints: env,metrics,trace,dump,jolokia,info,configprops,trace,logfile,refresh,flyway,liquibase,heapdump,loggers,auditevents,hystrix.stream 30 | turbine: 31 | clusters: default 32 | location: http://monitor:${turbine.stream.port} 33 | 34 | security: 35 | user: 36 | name: admin 37 | password: ${MONITOR_SERVER_PASSWORD:admin} -------------------------------------------------------------------------------- /monitor/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: monitor -------------------------------------------------------------------------------- /monitor/src/main/resources/logback-spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | cn.zhangxd 8 | spring-boot-cloud 9 | 1.0-SNAPSHOT 10 | pom 11 | ${project.artifactId} 12 | 13 | 14 | org.springframework.boot 15 | spring-boot-starter-parent 16 | 1.5.6.RELEASE 17 | 18 | 19 | 20 | 21 | config 22 | registry 23 | gateway 24 | monitor 25 | auth-service 26 | svca-service 27 | svcb-service 28 | zipkin 29 | 30 | 31 | 32 | UTF-8 33 | 1.8 34 | 1.0.0 35 | spring-boot-cloud 36 | Dalston.SR4 37 | 1.5.4 38 | 39 | 40 | 41 | 42 | org.springframework.boot 43 | spring-boot-starter-actuator 44 | 45 | 46 | org.springframework.boot 47 | spring-boot-starter-test 48 | test 49 | 50 | 51 | 52 | 53 | 54 | 55 | de.codecentric 56 | spring-boot-admin-server 57 | ${spring-boot-admin.version} 58 | 59 | 60 | de.codecentric 61 | spring-boot-admin-server-ui 62 | ${spring-boot-admin.version} 63 | 64 | 65 | de.codecentric 66 | spring-boot-admin-server-ui-hystrix 67 | ${spring-boot-admin.version} 68 | 69 | 70 | de.codecentric 71 | spring-boot-admin-server-ui-turbine 72 | ${spring-boot-admin.version} 73 | 74 | 75 | de.codecentric 76 | spring-boot-admin-server-ui-login 77 | ${spring-boot-admin.version} 78 | 79 | 80 | org.springframework.cloud 81 | spring-cloud-dependencies 82 | ${spring.cloud.version} 83 | pom 84 | import 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | org.springframework.boot 94 | spring-boot-maven-plugin 95 | 96 | 97 | 98 | repackage 99 | 100 | 101 | 102 | 103 | 104 | com.spotify 105 | docker-maven-plugin 106 | ${docker.plugin.version} 107 | 108 | 109 | package 110 | 111 | build 112 | 113 | 114 | 115 | 116 | ${docker.image.prefix}/${project.artifactId} 117 | ${project.basedir}/ 118 | 119 | 120 | / 121 | ${project.build.directory} 122 | ${project.build.finalName}.jar 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /registry/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM java:8 2 | VOLUME /tmp 3 | ADD ./target/registry.jar /app.jar 4 | RUN bash -c 'touch /app.jar' 5 | EXPOSE 8761 6 | ENTRYPOINT ["java","-jar","/app.jar"] -------------------------------------------------------------------------------- /registry/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | cn.zhangxd 9 | spring-boot-cloud 10 | 1.0-SNAPSHOT 11 | 12 | 13 | registry 14 | 1.0-SNAPSHOT 15 | jar 16 | ${project.artifactId} 17 | 18 | 19 | 20 | org.springframework.cloud 21 | spring-cloud-starter-eureka-server 22 | 23 | 24 | org.springframework.boot 25 | spring-boot-starter-security 26 | 27 | 28 | 29 | 30 | ${project.artifactId} 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-maven-plugin 35 | 36 | 37 | com.spotify 38 | docker-maven-plugin 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /registry/src/main/java/cn/zhangxd/registry/RegistryApplication.java: -------------------------------------------------------------------------------- 1 | package cn.zhangxd.registry; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; 6 | 7 | @SpringBootApplication 8 | @EnableEurekaServer 9 | public class RegistryApplication { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(RegistryApplication.class, args); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /registry/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8761 3 | 4 | eureka: 5 | instance: 6 | hostname: registry 7 | prefer-ip-address: true 8 | client: 9 | registerWithEureka: false 10 | fetchRegistry: false 11 | service-url: 12 | defaultZone: http://${security.user.name}:${security.user.password}@${eureka.instance.hostname}:${server.port}/eureka/ 13 | 14 | security: 15 | user: 16 | name: user 17 | password: ${REGISTRY_SERVER_PASSWORD:password} 18 | -------------------------------------------------------------------------------- /registry/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: registry -------------------------------------------------------------------------------- /registry/src/test/java/cn/zhangxd/registry/ApplicationTests.java: -------------------------------------------------------------------------------- 1 | package cn.zhangxd.registry; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.beans.factory.annotation.Value; 7 | import org.springframework.boot.test.context.SpringBootTest; 8 | import org.springframework.boot.test.web.client.TestRestTemplate; 9 | import org.springframework.http.HttpStatus; 10 | import org.springframework.http.ResponseEntity; 11 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 12 | 13 | import java.util.Map; 14 | 15 | import static org.junit.Assert.assertEquals; 16 | import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; 17 | 18 | @RunWith(SpringJUnit4ClassRunner.class) 19 | @SpringBootTest(webEnvironment = RANDOM_PORT) 20 | public class ApplicationTests { 21 | 22 | @Autowired 23 | private TestRestTemplate testRestTemplate; 24 | @Value("${security.user.name}") 25 | private String username; 26 | @Value("${security.user.password}") 27 | private String password; 28 | 29 | @Test 30 | public void catalogLoads() { 31 | @SuppressWarnings("rawtypes") 32 | ResponseEntity entity = 33 | testRestTemplate 34 | .withBasicAuth(username, password) 35 | .getForEntity("/eureka/apps", Map.class); 36 | assertEquals(HttpStatus.OK, entity.getStatusCode()); 37 | } 38 | 39 | @Test 40 | public void adminLoads() { 41 | @SuppressWarnings("rawtypes") 42 | ResponseEntity entity = 43 | testRestTemplate 44 | .withBasicAuth(username, password) 45 | .getForEntity("/env", Map.class); 46 | assertEquals(HttpStatus.OK, entity.getStatusCode()); 47 | } 48 | 49 | } -------------------------------------------------------------------------------- /screenshots/architecture.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxd1989/spring-boot-cloud/e3966d7cefa4fa429d13bbc8de7f4dafbae0de35/screenshots/architecture.jpg -------------------------------------------------------------------------------- /screenshots/components.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxd1989/spring-boot-cloud/e3966d7cefa4fa429d13bbc8de7f4dafbae0de35/screenshots/components.jpg -------------------------------------------------------------------------------- /screenshots/monitor1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxd1989/spring-boot-cloud/e3966d7cefa4fa429d13bbc8de7f4dafbae0de35/screenshots/monitor1.jpg -------------------------------------------------------------------------------- /screenshots/monitor10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxd1989/spring-boot-cloud/e3966d7cefa4fa429d13bbc8de7f4dafbae0de35/screenshots/monitor10.jpg -------------------------------------------------------------------------------- /screenshots/monitor11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxd1989/spring-boot-cloud/e3966d7cefa4fa429d13bbc8de7f4dafbae0de35/screenshots/monitor11.jpg -------------------------------------------------------------------------------- /screenshots/monitor12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxd1989/spring-boot-cloud/e3966d7cefa4fa429d13bbc8de7f4dafbae0de35/screenshots/monitor12.jpg -------------------------------------------------------------------------------- /screenshots/monitor2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxd1989/spring-boot-cloud/e3966d7cefa4fa429d13bbc8de7f4dafbae0de35/screenshots/monitor2.jpg -------------------------------------------------------------------------------- /screenshots/monitor3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxd1989/spring-boot-cloud/e3966d7cefa4fa429d13bbc8de7f4dafbae0de35/screenshots/monitor3.jpg -------------------------------------------------------------------------------- /screenshots/monitor4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxd1989/spring-boot-cloud/e3966d7cefa4fa429d13bbc8de7f4dafbae0de35/screenshots/monitor4.jpg -------------------------------------------------------------------------------- /screenshots/monitor5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxd1989/spring-boot-cloud/e3966d7cefa4fa429d13bbc8de7f4dafbae0de35/screenshots/monitor5.jpg -------------------------------------------------------------------------------- /screenshots/monitor6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxd1989/spring-boot-cloud/e3966d7cefa4fa429d13bbc8de7f4dafbae0de35/screenshots/monitor6.jpg -------------------------------------------------------------------------------- /screenshots/monitor7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxd1989/spring-boot-cloud/e3966d7cefa4fa429d13bbc8de7f4dafbae0de35/screenshots/monitor7.jpg -------------------------------------------------------------------------------- /screenshots/monitor8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxd1989/spring-boot-cloud/e3966d7cefa4fa429d13bbc8de7f4dafbae0de35/screenshots/monitor8.jpg -------------------------------------------------------------------------------- /screenshots/monitor9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxd1989/spring-boot-cloud/e3966d7cefa4fa429d13bbc8de7f4dafbae0de35/screenshots/monitor9.jpg -------------------------------------------------------------------------------- /screenshots/rabbit.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxd1989/spring-boot-cloud/e3966d7cefa4fa429d13bbc8de7f4dafbae0de35/screenshots/rabbit.jpg -------------------------------------------------------------------------------- /screenshots/registry.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxd1989/spring-boot-cloud/e3966d7cefa4fa429d13bbc8de7f4dafbae0de35/screenshots/registry.jpg -------------------------------------------------------------------------------- /screenshots/zipkin1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxd1989/spring-boot-cloud/e3966d7cefa4fa429d13bbc8de7f4dafbae0de35/screenshots/zipkin1.jpg -------------------------------------------------------------------------------- /screenshots/zipkin2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxd1989/spring-boot-cloud/e3966d7cefa4fa429d13bbc8de7f4dafbae0de35/screenshots/zipkin2.jpg -------------------------------------------------------------------------------- /screenshots/zipkin3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxd1989/spring-boot-cloud/e3966d7cefa4fa429d13bbc8de7f4dafbae0de35/screenshots/zipkin3.jpg -------------------------------------------------------------------------------- /svca-service/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM java:8 2 | VOLUME /tmp 3 | ADD ./target/svca-service.jar /app.jar 4 | RUN bash -c 'touch /app.jar' 5 | EXPOSE 8080 6 | ENTRYPOINT ["java","-jar","/app.jar"] -------------------------------------------------------------------------------- /svca-service/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | cn.zhangxd 9 | spring-boot-cloud 10 | 1.0-SNAPSHOT 11 | 12 | 13 | svca-service 14 | 1.0-SNAPSHOT 15 | jar 16 | ${project.artifactId} 17 | 18 | 19 | 20 | org.springframework.cloud 21 | spring-cloud-starter-oauth2 22 | 23 | 24 | 25 | org.springframework.cloud 26 | spring-cloud-starter-eureka 27 | 28 | 29 | 30 | org.springframework.cloud 31 | spring-cloud-starter-sleuth 32 | 33 | 34 | org.springframework.cloud 35 | spring-cloud-sleuth-stream 36 | 37 | 38 | org.springframework.cloud 39 | spring-cloud-stream-binder-rabbit 40 | 41 | 42 | 43 | org.springframework.cloud 44 | spring-cloud-starter-config 45 | 46 | 47 | org.springframework.cloud 48 | spring-cloud-starter-bus-amqp 49 | 50 | 51 | org.springframework.cloud 52 | spring-cloud-starter-feign 53 | 54 | 55 | org.springframework.cloud 56 | spring-cloud-starter-hystrix 57 | 58 | 59 | org.springframework.cloud 60 | spring-cloud-netflix-hystrix-stream 61 | 62 | 63 | org.springframework.cloud 64 | spring-cloud-starter-ribbon 65 | 66 | 67 | org.springframework.boot 68 | spring-boot-starter-aop 69 | 70 | 71 | org.springframework.retry 72 | spring-retry 73 | 74 | 75 | org.jolokia 76 | jolokia-core 77 | 78 | 79 | 80 | 81 | ${project.artifactId} 82 | 83 | 84 | org.springframework.boot 85 | spring-boot-maven-plugin 86 | 87 | 88 | com.spotify 89 | docker-maven-plugin 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /svca-service/src/main/java/cn/zhangxd/svca/ServiceAApplication.java: -------------------------------------------------------------------------------- 1 | package cn.zhangxd.svca; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; 6 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 7 | import org.springframework.cloud.netflix.feign.EnableFeignClients; 8 | import org.springframework.security.oauth2.config.annotation.web.configuration.EnableOAuth2Client; 9 | 10 | 11 | @EnableDiscoveryClient 12 | @EnableFeignClients 13 | @SpringBootApplication 14 | @EnableCircuitBreaker 15 | @EnableOAuth2Client 16 | public class ServiceAApplication { 17 | 18 | public static void main(String[] args) { 19 | SpringApplication.run(ServiceAApplication.class, args); 20 | } 21 | 22 | } -------------------------------------------------------------------------------- /svca-service/src/main/java/cn/zhangxd/svca/client/ServiceBClient.java: -------------------------------------------------------------------------------- 1 | package cn.zhangxd.svca.client; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.cloud.netflix.feign.FeignClient; 6 | import org.springframework.stereotype.Component; 7 | import org.springframework.web.bind.annotation.GetMapping; 8 | 9 | @FeignClient(name = "svcb-service", fallback = ServiceBClient.ServiceBClientFallback.class) 10 | public interface ServiceBClient { 11 | 12 | @GetMapping(value = "/") 13 | String printServiceB(); 14 | 15 | @Component 16 | class ServiceBClientFallback implements ServiceBClient { 17 | 18 | private static final Logger LOGGER = LoggerFactory.getLogger(ServiceBClientFallback.class); 19 | 20 | @Override 21 | public String printServiceB() { 22 | LOGGER.info("异常发生,进入fallback方法"); 23 | return "SERVICE B FAILED! - FALLING BACK"; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /svca-service/src/main/java/cn/zhangxd/svca/config/ServiceAConfiguration.java: -------------------------------------------------------------------------------- 1 | package cn.zhangxd.svca.config; 2 | 3 | import feign.RequestInterceptor; 4 | import org.springframework.cloud.security.oauth2.client.feign.OAuth2FeignRequestInterceptor; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; 8 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 9 | import org.springframework.security.oauth2.client.OAuth2ClientContext; 10 | import org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsResourceDetails; 11 | import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; 12 | import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; 13 | 14 | @Configuration 15 | @EnableResourceServer 16 | @EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true) 17 | public class ServiceAConfiguration extends ResourceServerConfigurerAdapter { 18 | 19 | @Bean 20 | public RequestInterceptor oauth2FeignRequestInterceptor(OAuth2ClientContext oauth2ClientContext, 21 | ClientCredentialsResourceDetails resource) { 22 | return new OAuth2FeignRequestInterceptor(oauth2ClientContext, resource); 23 | } 24 | 25 | @Override 26 | public void configure(HttpSecurity http) throws Exception { 27 | http.authorizeRequests() 28 | .anyRequest().authenticated(); 29 | } 30 | } -------------------------------------------------------------------------------- /svca-service/src/main/java/cn/zhangxd/svca/controller/ServiceAController.java: -------------------------------------------------------------------------------- 1 | package cn.zhangxd.svca.controller; 2 | 3 | import cn.zhangxd.svca.client.ServiceBClient; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.beans.factory.annotation.Value; 6 | import org.springframework.cloud.client.ServiceInstance; 7 | import org.springframework.cloud.context.config.annotation.RefreshScope; 8 | import org.springframework.cloud.netflix.eureka.EurekaDiscoveryClient; 9 | import org.springframework.web.bind.annotation.GetMapping; 10 | import org.springframework.web.bind.annotation.RestController; 11 | 12 | import java.security.Principal; 13 | 14 | @RefreshScope 15 | @RestController 16 | public class ServiceAController { 17 | 18 | @Value("${name:unknown}") 19 | private String name; 20 | 21 | @Autowired 22 | EurekaDiscoveryClient discoveryClient; 23 | @Autowired 24 | private ServiceBClient serviceBClient; 25 | 26 | @GetMapping(value = "/") 27 | public String printServiceA() { 28 | ServiceInstance serviceInstance = discoveryClient.getLocalServiceInstance(); 29 | return serviceInstance.getServiceId() + " (" + serviceInstance.getHost() + ":" + serviceInstance.getPort() + ")" + "===>name:" + name + "
" + serviceBClient.printServiceB(); 30 | } 31 | 32 | @GetMapping(path = "/current") 33 | public Principal getCurrentAccount(Principal principal) { 34 | return principal; 35 | } 36 | } -------------------------------------------------------------------------------- /svca-service/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: svca-service 4 | cloud: 5 | config: 6 | uri: http://config:8888 7 | fail-fast: true 8 | username: user 9 | password: ${CONFIG_SERVER_PASSWORD:password} 10 | retry: 11 | initial-interval: 2000 12 | max-interval: 10000 13 | multiplier: 2 14 | max-attempts: 10 15 | -------------------------------------------------------------------------------- /svca-service/src/main/resources/logback-spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /svcb-service/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM java:8 2 | VOLUME /tmp 3 | ADD ./target/svcb-service.jar /app.jar 4 | RUN bash -c 'touch /app.jar' 5 | EXPOSE 8070 6 | ENTRYPOINT ["java","-jar","/app.jar"] -------------------------------------------------------------------------------- /svcb-service/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | cn.zhangxd 9 | spring-boot-cloud 10 | 1.0-SNAPSHOT 11 | 12 | 13 | svcb-service 14 | 1.0-SNAPSHOT 15 | jar 16 | ${project.artifactId} 17 | 18 | 19 | 20 | org.springframework.cloud 21 | spring-cloud-starter-oauth2 22 | 23 | 24 | 25 | org.springframework.cloud 26 | spring-cloud-starter-eureka 27 | 28 | 29 | 30 | org.springframework.cloud 31 | spring-cloud-starter-sleuth 32 | 33 | 34 | org.springframework.cloud 35 | spring-cloud-sleuth-stream 36 | 37 | 38 | org.springframework.cloud 39 | spring-cloud-stream-binder-rabbit 40 | 41 | 42 | 43 | org.springframework.cloud 44 | spring-cloud-starter-config 45 | 46 | 47 | org.springframework.cloud 48 | spring-cloud-starter-bus-amqp 49 | 50 | 51 | org.springframework.cloud 52 | spring-cloud-starter-feign 53 | 54 | 55 | org.springframework.cloud 56 | spring-cloud-starter-hystrix 57 | 58 | 59 | org.springframework.cloud 60 | spring-cloud-netflix-hystrix-stream 61 | 62 | 63 | org.springframework.cloud 64 | spring-cloud-starter-ribbon 65 | 66 | 67 | org.springframework.boot 68 | spring-boot-starter-aop 69 | 70 | 71 | org.springframework.retry 72 | spring-retry 73 | 74 | 75 | org.jolokia 76 | jolokia-core 77 | 78 | 79 | 80 | 81 | ${project.artifactId} 82 | 83 | 84 | org.springframework.boot 85 | spring-boot-maven-plugin 86 | 87 | 88 | com.spotify 89 | docker-maven-plugin 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /svcb-service/src/main/java/cn/zhangxd/svcb/ServiceBApplication.java: -------------------------------------------------------------------------------- 1 | package cn.zhangxd.svcb; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; 6 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 7 | import org.springframework.cloud.netflix.feign.EnableFeignClients; 8 | import org.springframework.security.oauth2.config.annotation.web.configuration.EnableOAuth2Client; 9 | 10 | @EnableDiscoveryClient 11 | @EnableFeignClients 12 | @SpringBootApplication 13 | @EnableCircuitBreaker 14 | @EnableOAuth2Client 15 | public class ServiceBApplication { 16 | 17 | public static void main(String[] args) { 18 | SpringApplication.run(ServiceBApplication.class, args); 19 | } 20 | } -------------------------------------------------------------------------------- /svcb-service/src/main/java/cn/zhangxd/svcb/config/ServiceBConfiguration.java: -------------------------------------------------------------------------------- 1 | package cn.zhangxd.svcb.config; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; 5 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 6 | import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; 7 | import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; 8 | 9 | @Configuration 10 | @EnableResourceServer 11 | @EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true) 12 | public class ServiceBConfiguration extends ResourceServerConfigurerAdapter { 13 | 14 | @Override 15 | public void configure(HttpSecurity http) throws Exception { 16 | http.authorizeRequests() 17 | .anyRequest().authenticated(); 18 | } 19 | } -------------------------------------------------------------------------------- /svcb-service/src/main/java/cn/zhangxd/svcb/controller/ServiceBController.java: -------------------------------------------------------------------------------- 1 | package cn.zhangxd.svcb.controller; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.beans.factory.annotation.Value; 5 | import org.springframework.cloud.client.ServiceInstance; 6 | import org.springframework.cloud.context.config.annotation.RefreshScope; 7 | import org.springframework.cloud.netflix.eureka.EurekaDiscoveryClient; 8 | import org.springframework.web.bind.annotation.GetMapping; 9 | import org.springframework.web.bind.annotation.RestController; 10 | 11 | @RefreshScope 12 | @RestController 13 | public class ServiceBController { 14 | 15 | @Autowired 16 | EurekaDiscoveryClient discoveryClient; 17 | 18 | @Value("${msg:unknown}") 19 | private String msg; 20 | 21 | @GetMapping(value = "/") 22 | public String printServiceB() { 23 | ServiceInstance serviceInstance = discoveryClient.getLocalServiceInstance(); 24 | return serviceInstance.getServiceId() + " (" + serviceInstance.getHost() + ":" + serviceInstance.getPort() + ")" + "===>Say " + msg; 25 | } 26 | } -------------------------------------------------------------------------------- /svcb-service/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: svcb-service 4 | cloud: 5 | config: 6 | uri: http://config:8888 7 | fail-fast: true 8 | username: user 9 | password: ${CONFIG_SERVER_PASSWORD:password} 10 | retry: 11 | initial-interval: 2000 12 | max-interval: 10000 13 | multiplier: 2 14 | max-attempts: 10 -------------------------------------------------------------------------------- /svcb-service/src/main/resources/logback-spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /zipkin/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM java:8 2 | VOLUME /tmp 3 | ADD ./target/zipkin.jar /app.jar 4 | RUN bash -c 'touch /app.jar' 5 | EXPOSE 9411 6 | ENTRYPOINT ["java","-jar","/app.jar"] -------------------------------------------------------------------------------- /zipkin/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | cn.zhangxd 9 | spring-boot-cloud 10 | 1.0-SNAPSHOT 11 | 12 | 13 | zipkin 14 | 1.0-SNAPSHOT 15 | jar 16 | ${project.artifactId} 17 | 18 | 19 | 20 | org.springframework.cloud 21 | spring-cloud-sleuth-zipkin-stream 22 | 23 | 24 | org.springframework.cloud 25 | spring-cloud-starter-sleuth 26 | 27 | 28 | org.springframework.cloud 29 | spring-cloud-stream-binder-rabbit 30 | 31 | 32 | io.zipkin.java 33 | zipkin-autoconfigure-ui 34 | 35 | 36 | org.springframework.boot 37 | spring-boot-starter-security 38 | 39 | 40 | 41 | 42 | ${project.artifactId} 43 | 44 | 45 | org.springframework.boot 46 | spring-boot-maven-plugin 47 | 48 | 49 | com.spotify 50 | docker-maven-plugin 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /zipkin/src/main/java/cn/zhangxd/zipkin/ZipkinApplication.java: -------------------------------------------------------------------------------- 1 | package cn.zhangxd.zipkin; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.sleuth.zipkin.stream.EnableZipkinStreamServer; 6 | 7 | /** 8 | * @author zhangxd 9 | */ 10 | @SpringBootApplication 11 | @EnableZipkinStreamServer 12 | public class ZipkinApplication { 13 | 14 | public static void main(String[] args) { 15 | SpringApplication.run(ZipkinApplication.class, args); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /zipkin/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: zipkin 4 | rabbitmq: 5 | host: rabbitmq 6 | 7 | server: 8 | port: 9411 9 | 10 | security: 11 | user: 12 | name: admin 13 | password: ${ZIPKIN_SERVER_PASSWORD:admin} 14 | --------------------------------------------------------------------------------