├── zuul-gateway
├── README.md
├── doc
│ ├── gray_release_config.sql
│ └── gateway_api_route.sql
├── src
│ └── main
│ │ ├── java
│ │ └── com
│ │ │ └── zhouq
│ │ │ └── demo
│ │ │ └── zuul
│ │ │ └── gateway
│ │ │ ├── ZuulGatewayApplication.java
│ │ │ ├── GrayReleaseConfig.java
│ │ │ ├── RefreshRouteTask.java
│ │ │ ├── DynamicRouteConfiguration.java
│ │ │ ├── GrayReleaseConfigManager.java
│ │ │ ├── GatewayApiRoute.java
│ │ │ ├── GrayReleaseFilter.java
│ │ │ └── DynamicRouteLocator.java
│ │ └── resources
│ │ └── application.yml
└── pom.xml
├── doc
└── image
│ └── 1041568856705_.pic.jpg
├── order-service
├── src
│ └── main
│ │ ├── java
│ │ └── com
│ │ │ └── zhouq
│ │ │ └── order
│ │ │ └── service
│ │ │ ├── WmsService.java
│ │ │ ├── CreditService.java
│ │ │ ├── InventoryService.java
│ │ │ ├── PayService.java
│ │ │ ├── OrderServiceApplication.java
│ │ │ └── OrderController.java
│ │ └── resources
│ │ └── application.yml
└── pom.xml
├── .gitignore
├── credit-api
├── .gitignore
├── src
│ └── main
│ │ └── java
│ │ └── com
│ │ └── zhouq
│ │ └── credit
│ │ └── api
│ │ └── CreditApi.java
└── pom.xml
├── eureka-server
├── .gitignore
├── src
│ └── main
│ │ ├── resources
│ │ └── application.yml
│ │ └── java
│ │ └── com
│ │ └── zhouq
│ │ └── eurekaserver
│ │ └── EurekaServerApplication.java
└── pom.xml
├── pay-api
├── src
│ └── main
│ │ └── java
│ │ └── com
│ │ └── zhouq
│ │ └── pay_api
│ │ └── PayApi.java
└── pom.xml
├── credit-service
├── .gitignore
├── src
│ └── main
│ │ ├── resources
│ │ └── application.yml
│ │ └── java
│ │ └── com
│ │ └── zhouq
│ │ └── credit
│ │ └── service
│ │ ├── CreditServiceApplication.java
│ │ └── CreditService.java
└── pom.xml
├── pay-service
├── src
│ └── main
│ │ ├── resources
│ │ └── application.yml
│ │ └── java
│ │ └── com
│ │ └── zhouq
│ │ └── pay
│ │ └── service
│ │ ├── PayService.java
│ │ ├── PayServiceApplication.java
│ │ └── PayController.java
└── pom.xml
├── wms-service
├── src
│ └── main
│ │ ├── resources
│ │ └── application.yml
│ │ └── java
│ │ └── com
│ │ └── zhouq
│ │ └── wms
│ │ └── service
│ │ ├── WmsService.java
│ │ └── WmsServiceApplication.java
└── pom.xml
├── wms-api
├── src
│ └── main
│ │ └── java
│ │ └── com
│ │ └── zhouq
│ │ └── wms_api
│ │ └── WmsApi.java
└── pom.xml
├── inventory-service
├── src
│ └── main
│ │ ├── resources
│ │ └── application.yml
│ │ └── java
│ │ └── com
│ │ └── zhouq
│ │ └── inventory
│ │ └── service
│ │ ├── InventoryService.java
│ │ └── InventoryServiceApplication.java
└── pom.xml
├── inventory-api
├── src
│ └── main
│ │ └── java
│ │ └── com
│ │ └── zhouq
│ │ └── inventory
│ │ └── api
│ │ └── InventoryApi.java
└── pom.xml
├── pom.xml
└── README.md
/zuul-gateway/README.md:
--------------------------------------------------------------------------------
1 | zuul 二次开发,实现了动态路由
2 |
--------------------------------------------------------------------------------
/doc/image/1041568856705_.pic.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/heyxyw/spring-cloud/HEAD/doc/image/1041568856705_.pic.jpg
--------------------------------------------------------------------------------
/order-service/src/main/java/com/zhouq/order/service/WmsService.java:
--------------------------------------------------------------------------------
1 | package com.zhouq.order.service;
2 |
3 | import org.springframework.cloud.netflix.feign.FeignClient;
4 |
5 | import com.zhouq.wms_api.WmsApi;
6 |
7 | @FeignClient(value = "wms-service")
8 | public interface WmsService extends WmsApi {
9 |
10 | }
--------------------------------------------------------------------------------
/order-service/src/main/java/com/zhouq/order/service/CreditService.java:
--------------------------------------------------------------------------------
1 | package com.zhouq.order.service;
2 |
3 | import org.springframework.cloud.netflix.feign.FeignClient;
4 |
5 | import com.zhouq.credit.api.CreditApi;
6 |
7 | @FeignClient(value = "credit-service")
8 | public interface CreditService extends CreditApi {
9 |
10 | }
--------------------------------------------------------------------------------
/order-service/src/main/java/com/zhouq/order/service/InventoryService.java:
--------------------------------------------------------------------------------
1 | package com.zhouq.order.service;
2 |
3 | import org.springframework.cloud.netflix.feign.FeignClient;
4 |
5 | import com.zhouq.inventory.api.InventoryApi;
6 |
7 | @FeignClient(value = "inventory-service")
8 | public interface InventoryService extends InventoryApi {
9 |
10 | }
--------------------------------------------------------------------------------
/order-service/src/main/java/com/zhouq/order/service/PayService.java:
--------------------------------------------------------------------------------
1 | package com.zhouq.order.service;
2 |
3 | import com.zhouq.pay_api.PayApi;
4 | import org.springframework.cloud.netflix.feign.FeignClient;
5 |
6 | /**
7 | * Create by zhouq on 2019/8/8
8 | */
9 | @FeignClient(value = "pay-service")
10 | public interface PayService extends PayApi {
11 | }
12 |
--------------------------------------------------------------------------------
/zuul-gateway/doc/gray_release_config.sql:
--------------------------------------------------------------------------------
1 |
2 | CREATE TABLE `gray_release_config` (
3 | `id` int(11) NOT NULL AUTO_INCREMENT,
4 | `service_id` varchar(255) DEFAULT NULL,
5 | `path` varchar(255) DEFAULT NULL,
6 | `enable_gray_release` int(11) DEFAULT NULL,
7 | PRIMARY KEY (`id`)
8 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
9 |
10 |
11 | INSERT INTO `gray_release_config` (`id`, `service_id`, `path`, `enable_gray_release`) VALUES ('1', 'order-service', '/order', '1');
12 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | target/
3 | !.mvn/wrapper/maven-wrapper.jar
4 | !**/src/main/**
5 | !**/src/test/**
6 |
7 | ### STS ###
8 | .apt_generated
9 | .classpath
10 | .factorypath
11 | .project
12 | .settings
13 | .springBeans
14 | .sts4-cache
15 |
16 | ### IntelliJ IDEA ###
17 | .idea
18 | *.iws
19 | *.iml
20 | *.ipr
21 |
22 | ### NetBeans ###
23 | /nbproject/private/
24 | /nbbuild/
25 | /dist/
26 | /nbdist/
27 | /.nb-gradle/
28 | build/
29 |
30 | ### VS Code ###
31 | .vscode/
32 |
--------------------------------------------------------------------------------
/credit-api/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | target/
3 | !.mvn/wrapper/maven-wrapper.jar
4 | !**/src/main/**
5 | !**/src/test/**
6 |
7 | ### STS ###
8 | .apt_generated
9 | .classpath
10 | .factorypath
11 | .project
12 | .settings
13 | .springBeans
14 | .sts4-cache
15 |
16 | ### IntelliJ IDEA ###
17 | .idea
18 | *.iws
19 | *.iml
20 | *.ipr
21 |
22 | ### NetBeans ###
23 | /nbproject/private/
24 | /nbbuild/
25 | /dist/
26 | /nbdist/
27 | /.nb-gradle/
28 | build/
29 |
30 | ### VS Code ###
31 | .vscode/
32 |
--------------------------------------------------------------------------------
/eureka-server/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | target/
3 | !.mvn/wrapper/maven-wrapper.jar
4 | !**/src/main/**
5 | !**/src/test/**
6 |
7 | ### STS ###
8 | .apt_generated
9 | .classpath
10 | .factorypath
11 | .project
12 | .settings
13 | .springBeans
14 | .sts4-cache
15 |
16 | ### IntelliJ IDEA ###
17 | .idea
18 | *.iws
19 | *.iml
20 | *.ipr
21 |
22 | ### NetBeans ###
23 | /nbproject/private/
24 | /nbbuild/
25 | /dist/
26 | /nbdist/
27 | /.nb-gradle/
28 | build/
29 |
30 | ### VS Code ###
31 | .vscode/
32 |
--------------------------------------------------------------------------------
/pay-api/src/main/java/com/zhouq/pay_api/PayApi.java:
--------------------------------------------------------------------------------
1 | package com.zhouq.pay_api;
2 |
3 | import org.springframework.web.bind.annotation.PathVariable;
4 | import org.springframework.web.bind.annotation.RequestMapping;
5 | import org.springframework.web.bind.annotation.RequestMethod;
6 |
7 | @RequestMapping("/pay")
8 | public interface PayApi {
9 |
10 | @RequestMapping(value = "/pay/{orderId}", method = RequestMethod.PUT)
11 | String pay(@PathVariable("orderId") Long orderId);
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/credit-service/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | target/
3 | !.mvn/wrapper/maven-wrapper.jar
4 | !**/src/main/**
5 | !**/src/test/**
6 |
7 | ### STS ###
8 | .apt_generated
9 | .classpath
10 | .factorypath
11 | .project
12 | .settings
13 | .springBeans
14 | .sts4-cache
15 |
16 | ### IntelliJ IDEA ###
17 | .idea
18 | *.iws
19 | *.iml
20 | *.ipr
21 |
22 | ### NetBeans ###
23 | /nbproject/private/
24 | /nbbuild/
25 | /dist/
26 | /nbdist/
27 | /.nb-gradle/
28 | build/
29 |
30 | ### VS Code ###
31 | .vscode/
32 |
--------------------------------------------------------------------------------
/pay-service/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | server:
2 | port: 8085
3 |
4 | spring:
5 | application:
6 | name: pay-service
7 |
8 | eureka:
9 | instance:
10 | hostname: localhost
11 | client:
12 | serviceUrl:
13 | defaultZone: http://localhost:8761/eureka
14 | registry-fetch-interval-seconds: 1
15 | instance-info-replication-interval-seconds: 1
16 |
17 | ribbon:
18 | eager-load:
19 | enabled: true
20 |
21 | feign:
22 | hystrix:
23 | enabled: false
--------------------------------------------------------------------------------
/wms-service/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | server:
2 | port: 8083
3 |
4 | spring:
5 | application:
6 | name: wms-service
7 |
8 | eureka:
9 | instance:
10 | hostname: localhost
11 | client:
12 | serviceUrl:
13 | defaultZone: http://localhost:8761/eureka
14 | registry-fetch-interval-seconds: 1
15 | instance-info-replication-interval-seconds: 1
16 |
17 | ribbon:
18 | eager-load:
19 | enabled: true
20 |
21 | feign:
22 | hystrix:
23 | enabled: false
--------------------------------------------------------------------------------
/wms-api/src/main/java/com/zhouq/wms_api/WmsApi.java:
--------------------------------------------------------------------------------
1 | package com.zhouq.wms_api;
2 |
3 | import org.springframework.web.bind.annotation.PathVariable;
4 | import org.springframework.web.bind.annotation.RequestMapping;
5 | import org.springframework.web.bind.annotation.RequestMethod;
6 |
7 | @RequestMapping("/wms")
8 | public interface WmsApi {
9 |
10 | @RequestMapping(value = "/delivery/{productId}", method = RequestMethod.PUT)
11 | String delivery(@PathVariable("productId") Long productId);
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/eureka-server/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | server:
2 | port: 8761
3 | eureka:
4 | instance:
5 | hostname: localhost
6 | # 服务超过2 秒没有上报,就视为
7 | lease-expiration-duration-in-seconds: 2
8 | client:
9 | registerWithEureka: false
10 | fetchRegistry: false
11 | serviceUrl:
12 | defaultZone: http://localhost:8761/eureka/
13 | server:
14 | enableSelfPreservation: false
15 | response-cache-update-interval-ms: 100
16 | # 每隔多少秒去检查心跳
17 | eviction-interval-timer-in-ms: 1000
--------------------------------------------------------------------------------
/credit-service/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | server:
2 | port: 8081
3 |
4 | spring:
5 | application:
6 | name: credit-service
7 |
8 | eureka:
9 | instance:
10 | hostname: localhost
11 | client:
12 | serviceUrl:
13 | defaultZone: http://localhost:8761/eureka
14 | registry-fetch-interval-seconds: 1
15 | instance-info-replication-interval-seconds: 1
16 |
17 |
18 | ribbon:
19 | eager-load:
20 | enabled: true
21 |
22 | feign:
23 | hystrix:
24 | enabled: false
--------------------------------------------------------------------------------
/inventory-service/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | server:
2 | port: 8082
3 |
4 | spring:
5 | application:
6 | name: inventory-service
7 |
8 | eureka:
9 | instance:
10 | hostname: localhost
11 | client:
12 | serviceUrl:
13 | defaultZone: http://localhost:8761/eureka
14 | registry-fetch-interval-seconds: 1
15 | instance-info-replication-interval-seconds: 1
16 |
17 | ribbon:
18 | eager-load:
19 | enabled: true
20 |
21 | feign:
22 | hystrix:
23 | enabled: false
--------------------------------------------------------------------------------
/pay-service/src/main/java/com/zhouq/pay/service/PayService.java:
--------------------------------------------------------------------------------
1 | package com.zhouq.Pay.service;
2 |
3 | import org.springframework.web.bind.annotation.PathVariable;
4 | import org.springframework.web.bind.annotation.RestController;
5 |
6 | import com.zhouq.pay_api.PayApi;
7 |
8 | @RestController
9 | public class PayService implements PayApi {
10 |
11 | public String pay(@PathVariable("orderId") Long orderId) {
12 | System.out.println("对订单进行支付【orderId=" + orderId + "】");
13 | return "{'msg': 'success'}";
14 | }
15 |
16 | }
--------------------------------------------------------------------------------
/wms-service/src/main/java/com/zhouq/wms/service/WmsService.java:
--------------------------------------------------------------------------------
1 | package com.zhouq.wms.service;
2 |
3 | import org.springframework.web.bind.annotation.PathVariable;
4 | import org.springframework.web.bind.annotation.RestController;
5 |
6 | import com.zhouq.wms_api.WmsApi;
7 |
8 | @RestController
9 | public class WmsService implements WmsApi {
10 |
11 | public String delivery(@PathVariable("productId") Long productId) {
12 | System.out.println("对商品【productId=" + productId + "】进行发货");
13 | return "{'msg': 'success'}";
14 | }
15 |
16 | }
--------------------------------------------------------------------------------
/zuul-gateway/src/main/java/com/zhouq/demo/zuul/gateway/ZuulGatewayApplication.java:
--------------------------------------------------------------------------------
1 | package com.zhouq.demo.zuul.gateway;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
6 |
7 | @SpringBootApplication
8 | @EnableZuulProxy
9 | public class ZuulGatewayApplication {
10 |
11 | public static void main(String[] args) {
12 | SpringApplication.run(ZuulGatewayApplication.class, args);
13 | }
14 |
15 | }
--------------------------------------------------------------------------------
/order-service/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | server:
2 | port: 9090
3 |
4 | spring:
5 | application:
6 | name: order-service
7 |
8 | eureka:
9 | instance:
10 | hostname: localhost
11 | metadata-map:
12 | version: current
13 | client:
14 | serviceUrl:
15 | defaultZone: http://localhost:8761/eureka
16 | registry-fetch-interval-seconds: 1
17 | instance-info-replication-interval-seconds: 1
18 |
19 | ribbon:
20 | eager-load:
21 | enabled: true
22 |
23 | feign:
24 | hystrix:
25 | enabled: false
--------------------------------------------------------------------------------
/eureka-server/src/main/java/com/zhouq/eurekaserver/EurekaServerApplication.java:
--------------------------------------------------------------------------------
1 | package com.zhouq.eurekaserver;
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 EurekaServerApplication {
10 |
11 | public static void main(String[] args) {
12 | SpringApplication.run(EurekaServerApplication.class, args);
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/credit-api/src/main/java/com/zhouq/credit/api/CreditApi.java:
--------------------------------------------------------------------------------
1 | package com.zhouq.credit.api;
2 |
3 | import org.springframework.web.bind.annotation.PathVariable;
4 | import org.springframework.web.bind.annotation.RequestMapping;
5 | import org.springframework.web.bind.annotation.RequestMethod;
6 |
7 | @RequestMapping("/credit")
8 | public interface CreditApi {
9 |
10 | @RequestMapping(value = "/add/{userId}/{credit}", method = RequestMethod.PUT)
11 | String add(
12 | @PathVariable("userId") Long userId,
13 | @PathVariable("credit") Long credit);
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/inventory-api/src/main/java/com/zhouq/inventory/api/InventoryApi.java:
--------------------------------------------------------------------------------
1 | package com.zhouq.inventory.api;
2 |
3 | import org.springframework.web.bind.annotation.PathVariable;
4 | import org.springframework.web.bind.annotation.RequestMapping;
5 | import org.springframework.web.bind.annotation.RequestMethod;
6 |
7 | @RequestMapping("/inventory")
8 | public interface InventoryApi {
9 |
10 | @RequestMapping(value = "/deduct/{productId}/{stock}", method = RequestMethod.PUT)
11 | String deductStock(
12 | @PathVariable("productId") Long productId,
13 | @PathVariable("stock") Long stock);
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/pay-service/src/main/java/com/zhouq/pay/service/PayServiceApplication.java:
--------------------------------------------------------------------------------
1 | package com.zhouq.pay.service;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
6 |
7 | /**
8 | * 服务A的启动类
9 | * @author zhonghuashishan
10 | *
11 | */
12 | @SpringBootApplication
13 | @EnableEurekaClient
14 | public class PayServiceApplication {
15 |
16 | public static void main(String[] args) {
17 | SpringApplication.run(PayServiceApplication.class, args);
18 | }
19 |
20 | }
--------------------------------------------------------------------------------
/wms-service/src/main/java/com/zhouq/wms/service/WmsServiceApplication.java:
--------------------------------------------------------------------------------
1 | package com.zhouq.wms.service;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
6 |
7 | /**
8 | * 服务A的启动类
9 | * @author zhonghuashishan
10 | *
11 | */
12 | @SpringBootApplication
13 | @EnableEurekaClient
14 | public class WmsServiceApplication {
15 |
16 | public static void main(String[] args) {
17 | SpringApplication.run(WmsServiceApplication.class, args);
18 | }
19 |
20 | }
--------------------------------------------------------------------------------
/credit-service/src/main/java/com/zhouq/credit/service/CreditServiceApplication.java:
--------------------------------------------------------------------------------
1 | package com.zhouq.credit.service;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
6 |
7 | /**
8 | * 服务A的启动类
9 | *
10 | * @author zhouq
11 | */
12 | @SpringBootApplication
13 | @EnableEurekaClient
14 | public class CreditServiceApplication {
15 |
16 | public static void main(String[] args) {
17 | SpringApplication.run(CreditServiceApplication.class, args);
18 | }
19 |
20 | }
--------------------------------------------------------------------------------
/credit-service/src/main/java/com/zhouq/credit/service/CreditService.java:
--------------------------------------------------------------------------------
1 | package com.zhouq.credit.service;
2 |
3 | import org.springframework.web.bind.annotation.PathVariable;
4 | import org.springframework.web.bind.annotation.RestController;
5 |
6 | import com.zhouq.credit.api.CreditApi;
7 |
8 | @RestController
9 | public class CreditService implements CreditApi {
10 |
11 | public String add(@PathVariable("userId") Long userId,
12 | @PathVariable("credit") Long credit) {
13 | System.out.println("对用户【userId=" + userId + "】增加积分:" + credit);
14 | return "{'msg': 'success'}";
15 | }
16 |
17 | }
--------------------------------------------------------------------------------
/inventory-service/src/main/java/com/zhouq/inventory/service/InventoryService.java:
--------------------------------------------------------------------------------
1 | package com.zhouq.inventory.service;
2 |
3 | import org.springframework.web.bind.annotation.PathVariable;
4 | import org.springframework.web.bind.annotation.RestController;
5 |
6 | import com.zhouq.inventory.api.InventoryApi;
7 |
8 | @RestController
9 | public class InventoryService implements InventoryApi {
10 |
11 | public String deductStock(@PathVariable("productId") Long productId,
12 | @PathVariable("stock") Long stock) {
13 | System.out.println("对商品【productId=" + productId + "】扣减库存:" + stock);
14 | return "{'msg': 'success'}";
15 | }
16 |
17 | }
--------------------------------------------------------------------------------
/inventory-service/src/main/java/com/zhouq/inventory/service/InventoryServiceApplication.java:
--------------------------------------------------------------------------------
1 | package com.zhouq.inventory.service;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
6 |
7 | /**
8 | * 服务A的启动类
9 | * @author zhonghuashishan
10 | *
11 | */
12 | @SpringBootApplication
13 | @EnableEurekaClient
14 | public class InventoryServiceApplication {
15 |
16 | public static void main(String[] args) {
17 | SpringApplication.run(InventoryServiceApplication.class, args);
18 | }
19 |
20 | }
--------------------------------------------------------------------------------
/order-service/src/main/java/com/zhouq/order/service/OrderServiceApplication.java:
--------------------------------------------------------------------------------
1 | package com.zhouq.order.service;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
6 | import org.springframework.cloud.netflix.feign.EnableFeignClients;
7 |
8 | @SpringBootApplication
9 | @EnableEurekaClient
10 | @EnableFeignClients
11 | public class OrderServiceApplication {
12 |
13 | public static void main(String[] args) {
14 | SpringApplication.run(OrderServiceApplication.class, args);
15 | }
16 |
17 | }
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 | com.zhss
6 | spring-cloud
7 | 0.0.1-SNAPSHOT
8 | pom
9 | spring-cloud
10 | Demo project for Spring Boot
11 |
12 |
13 | 1.8
14 | 1.8
15 |
16 |
17 |
--------------------------------------------------------------------------------
/pay-service/src/main/java/com/zhouq/pay/service/PayController.java:
--------------------------------------------------------------------------------
1 | package com.zhouq.pay.service;
2 |
3 | import org.springframework.web.bind.annotation.RequestMapping;
4 | import org.springframework.web.bind.annotation.RequestMethod;
5 | import org.springframework.web.bind.annotation.RequestParam;
6 | import org.springframework.web.bind.annotation.RestController;
7 |
8 | /**
9 | * Create by zhouq on 2019/8/8
10 | */
11 | @RestController
12 | @RequestMapping("/pay")
13 | public class PayController {
14 |
15 | @RequestMapping(value = "/order", method = RequestMethod.GET)
16 | public String greeting(
17 | @RequestParam("orderId") Long orderId) {
18 | System.out.println("支付订单:" + orderId);
19 | return "success";
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/zuul-gateway/doc/gateway_api_route.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE `gateway_api_route` (
2 | `id` varchar(50) NOT NULL,
3 | `path` varchar(255) NOT NULL,
4 | `service_id` varchar(50) DEFAULT NULL,
5 | `url` varchar(255) DEFAULT NULL,
6 | `retryable` tinyint(1) DEFAULT NULL,
7 | `enabled` tinyint(1) NOT NULL,
8 | `strip_prefix` int(11) DEFAULT NULL,
9 | `api_name` varchar(255) DEFAULT NULL,
10 | PRIMARY KEY (`id`)
11 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8
12 |
13 | INSERT INTO gateway_api_route (id, path, service_id, retryable, strip_prefix, url, enabled) VALUES ('order-service', '/order/**', 'order-service',0,1, NULL, 1);
14 | INSERT INTO gateway_api_route (`id`, `path`, `service_id`, `url`, `retryable`, `enabled`, `strip_prefix`, `api_name`) VALUES ('pay-service', '/pay-v1/**', 'pay-service', NULL, '0', '1', '1', NULL);
15 |
16 |
--------------------------------------------------------------------------------
/pay-api/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | com.zhouq
6 | pay-api
7 | 0.0.1-SNAPSHOT
8 | jar
9 |
10 | pay-api
11 | http://maven.apache.org
12 |
13 |
14 | UTF-8
15 | 1.8
16 | 1.8
17 |
18 |
19 |
20 |
21 | org.springframework.boot
22 | spring-boot-starter-web
23 | 1.5.13.RELEASE
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/wms-api/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | com.zhouq
6 | wms-api
7 | 0.0.1-SNAPSHOT
8 | jar
9 |
10 | wms-api
11 | http://maven.apache.org
12 |
13 |
14 | UTF-8
15 | 1.8
16 | 1.8
17 |
18 |
19 |
20 |
21 | org.springframework.boot
22 | spring-boot-starter-web
23 | 1.5.13.RELEASE
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/inventory-api/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | com.zhouq
6 | inventory-api
7 | 0.0.1-SNAPSHOT
8 | jar
9 |
10 | inventory-api
11 | http://maven.apache.org
12 |
13 |
14 | UTF-8
15 | 1.8
16 | 1.8
17 |
18 |
19 |
20 |
21 | org.springframework.boot
22 | spring-boot-starter-web
23 | 1.5.13.RELEASE
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/zuul-gateway/src/main/java/com/zhouq/demo/zuul/gateway/GrayReleaseConfig.java:
--------------------------------------------------------------------------------
1 | package com.zhouq.demo.zuul.gateway;
2 |
3 | /**
4 | * Create by zhouq on 2019/8/11
5 | */
6 | public class GrayReleaseConfig {
7 | private int id;
8 | private String serviceId;
9 | private String path;
10 | private int enableGrayRelease;
11 |
12 | public int getId() {
13 | return id;
14 | }
15 |
16 | public void setId(int id) {
17 | this.id = id;
18 | }
19 |
20 | public String getServiceId() {
21 | return serviceId;
22 | }
23 |
24 | public void setServiceId(String serviceId) {
25 | this.serviceId = serviceId;
26 | }
27 |
28 | public String getPath() {
29 | return path;
30 | }
31 |
32 | public void setPath(String path) {
33 | this.path = path;
34 | }
35 |
36 | public int getEnableGrayRelease() {
37 | return enableGrayRelease;
38 | }
39 |
40 | public void setEnableGrayRelease(int enableGrayRelease) {
41 | this.enableGrayRelease = enableGrayRelease;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/credit-api/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | com.zhouq
7 | credit-api
8 | 0.0.1-SNAPSHOT
9 |
10 | credit-api
11 | Demo project for Spring Boot
12 |
13 |
14 | UTF-8
15 | 1.8
16 | 1.8
17 |
18 |
19 |
20 |
21 | org.springframework.boot
22 | spring-boot-starter-web
23 | 1.5.13.RELEASE
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/zuul-gateway/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | server:
2 | port: 9000
3 |
4 | spring:
5 | application:
6 | name: zuul-gateway
7 | datasource:
8 | url: jdbc:mysql://localhost:3306/springcloud?autoReconnect=true&useUnicode=true&characterEncoding=utf-8
9 | username: root
10 | password: root
11 | driver-class-name: com.mysql.jdbc.Driver
12 |
13 | eureka:
14 | instance:
15 | hostname: localhost
16 |
17 | client:
18 | serviceUrl:
19 | defaultZone: http://localhost:8761/eureka/
20 |
21 | zuul:
22 | retryable: true
23 | # ribbon:
24 | # eager-load:
25 | # enabled: true
26 | # routes:
27 | # order-service:
28 | # path: /xx1/**
29 |
30 |
31 | ribbon:
32 | eager-load:
33 | enabled: true
34 | ConnectTimeout: 3000
35 | ReadTimeout: 3000
36 | OkToRetryOnAllOperations: true
37 | MaxAutoRetries: 1
38 | MaxAutoRetriesNextServer: 1
39 |
40 | feign:
41 | hystrix:
42 | enabled: false
43 |
44 |
45 | hystrix:
46 | command:
47 | default:
48 | execution:
49 | isolation:
50 | thread:
51 | timeoutInMilliseconds: 10000
--------------------------------------------------------------------------------
/zuul-gateway/src/main/java/com/zhouq/demo/zuul/gateway/RefreshRouteTask.java:
--------------------------------------------------------------------------------
1 | package com.zhouq.demo.zuul.gateway;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.cloud.netflix.zuul.RoutesRefreshedEvent;
5 | import org.springframework.cloud.netflix.zuul.filters.RouteLocator;
6 | import org.springframework.context.ApplicationEventPublisher;
7 | import org.springframework.context.annotation.Configuration;
8 | import org.springframework.scheduling.annotation.EnableScheduling;
9 | import org.springframework.scheduling.annotation.Scheduled;
10 |
11 | /**
12 | * 发送定时事件
13 | */
14 | @Configuration
15 | @EnableScheduling
16 | public class RefreshRouteTask {
17 |
18 | @Autowired
19 | private ApplicationEventPublisher publisher;
20 |
21 | @Autowired
22 | private RouteLocator routeLocator;
23 |
24 | @Scheduled(fixedRate = 5000)
25 | private void refreshRoute() {
26 | System.out.println("定时刷新路由表。。。。");
27 | RoutesRefreshedEvent routesRefreshedEvent = new RoutesRefreshedEvent(routeLocator);
28 | publisher.publishEvent(routesRefreshedEvent);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/zuul-gateway/src/main/java/com/zhouq/demo/zuul/gateway/DynamicRouteConfiguration.java:
--------------------------------------------------------------------------------
1 | package com.zhouq.demo.zuul.gateway;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.boot.autoconfigure.web.ServerProperties;
5 | import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
6 | import org.springframework.context.annotation.Bean;
7 | import org.springframework.context.annotation.Configuration;
8 | import org.springframework.jdbc.core.JdbcTemplate;
9 |
10 | /**
11 | * Create by zhouq on 2019/8/8
12 | */
13 | @Configuration
14 | public class DynamicRouteConfiguration {
15 | @Autowired
16 | private ZuulProperties zuulProperties;
17 |
18 | @Autowired
19 | private ServerProperties server;
20 |
21 | @Autowired
22 | private JdbcTemplate jdbcTemplate;
23 |
24 | @Bean
25 | public DynamicRouteLocator routeLocator() {
26 | DynamicRouteLocator dynamicRouteLocator = new DynamicRouteLocator(
27 | this.server.getServletPrefix(), this.zuulProperties);
28 | dynamicRouteLocator.setJdbcTemplate(jdbcTemplate);
29 | return dynamicRouteLocator;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/order-service/src/main/java/com/zhouq/order/service/OrderController.java:
--------------------------------------------------------------------------------
1 | package com.zhouq.order.service;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.web.bind.annotation.RequestMapping;
5 | import org.springframework.web.bind.annotation.RequestMethod;
6 | import org.springframework.web.bind.annotation.RequestParam;
7 | import org.springframework.web.bind.annotation.RestController;
8 |
9 | @RestController
10 | @RequestMapping("/order")
11 | public class OrderController {
12 |
13 | @Autowired
14 | private InventoryService inventoryService;
15 | @Autowired
16 | private WmsService wmsService;
17 | @Autowired
18 | private CreditService creditService;
19 |
20 | @Autowired
21 | private PayService payService;
22 |
23 | @RequestMapping(value = "/create", method = RequestMethod.GET)
24 | public String greeting(
25 | @RequestParam("productId") Long productId,
26 | @RequestParam("userId") Long userId,
27 | @RequestParam("count") Long count,
28 | @RequestParam("totalPrice") Long totalPrice) {
29 | System.out.println("创建订单");
30 | inventoryService.deductStock(productId, count);
31 | wmsService.delivery(productId);
32 | creditService.add(userId, totalPrice);
33 | // payService.pay(12434L);
34 | return "success";
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/zuul-gateway/src/main/java/com/zhouq/demo/zuul/gateway/GrayReleaseConfigManager.java:
--------------------------------------------------------------------------------
1 | package com.zhouq.demo.zuul.gateway;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.context.annotation.Configuration;
5 | import org.springframework.jdbc.core.BeanPropertyRowMapper;
6 | import org.springframework.jdbc.core.JdbcTemplate;
7 | import org.springframework.scheduling.annotation.EnableScheduling;
8 | import org.springframework.scheduling.annotation.Scheduled;
9 |
10 | import java.util.List;
11 | import java.util.Map;
12 | import java.util.concurrent.ConcurrentHashMap;
13 |
14 | /**
15 | * Create by zhouq on 2019/8/11
16 | *
17 | * 获取数据库的灰度发布信息.
18 | */
19 | @Configuration
20 | @EnableScheduling
21 | public class GrayReleaseConfigManager {
22 |
23 | private Map grayReleaseConfigs = new ConcurrentHashMap();
24 |
25 | @Autowired
26 | private JdbcTemplate jdbcTemplate;
27 |
28 | @Scheduled(fixedRate = 1000)
29 | private void refreshRoute() {
30 | //查询数据库,获取需要灰度发布信息
31 |
32 | List results = jdbcTemplate.query(
33 | "select * from gray_release_config",
34 | new BeanPropertyRowMapper<>(GrayReleaseConfig.class)
35 | );
36 |
37 | for (GrayReleaseConfig grayReleaseConfig : results) {
38 | grayReleaseConfigs.put(grayReleaseConfig.getPath(), grayReleaseConfig);
39 | }
40 | }
41 |
42 | public Map getGrayReleaseConfigs() {
43 | return grayReleaseConfigs;
44 | }
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/zuul-gateway/src/main/java/com/zhouq/demo/zuul/gateway/GatewayApiRoute.java:
--------------------------------------------------------------------------------
1 | package com.zhouq.demo.zuul.gateway;
2 |
3 | /**
4 | * Create by zhouq on 2019/8/8
5 | */
6 | public class GatewayApiRoute {
7 | private String id;
8 | private String path;
9 | private String serviceId;
10 | private String url;
11 | private boolean stripPrefix = true;
12 | private Boolean retryable;
13 | private Boolean enabled;
14 |
15 | public String getId() {
16 | return id;
17 | }
18 |
19 | public void setId(String id) {
20 | this.id = id;
21 | }
22 |
23 | public String getPath() {
24 | return path;
25 | }
26 |
27 | public void setPath(String path) {
28 | this.path = path;
29 | }
30 |
31 | public String getServiceId() {
32 | return serviceId;
33 | }
34 |
35 | public void setServiceId(String serviceId) {
36 | this.serviceId = serviceId;
37 | }
38 |
39 | public String getUrl() {
40 | return url;
41 | }
42 |
43 | public void setUrl(String url) {
44 | this.url = url;
45 | }
46 |
47 | public boolean isStripPrefix() {
48 | return stripPrefix;
49 | }
50 |
51 | public void setStripPrefix(boolean stripPrefix) {
52 | this.stripPrefix = stripPrefix;
53 | }
54 |
55 | public Boolean getRetryable() {
56 | return retryable;
57 | }
58 |
59 | public void setRetryable(Boolean retryable) {
60 | this.retryable = retryable;
61 | }
62 |
63 | public Boolean getEnabled() {
64 | return enabled;
65 | }
66 |
67 | public void setEnabled(Boolean enabled) {
68 | this.enabled = enabled;
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/pay-service/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | com.zhouq
6 | pay-service
7 | 0.0.1-SNAPSHOT
8 | jar
9 |
10 | pay-service
11 | http://maven.apache.org
12 |
13 |
14 | UTF-8
15 | 1.8
16 | 1.8
17 |
18 |
19 |
20 | org.springframework.boot
21 | spring-boot-starter-parent
22 | 1.5.13.RELEASE
23 |
24 |
25 |
26 |
27 |
28 | org.springframework.cloud
29 | spring-cloud-dependencies
30 | Edgware.SR3
31 | pom
32 | import
33 |
34 |
35 |
36 |
37 |
38 |
39 | org.springframework.cloud
40 | spring-cloud-starter-config
41 |
42 |
43 | org.springframework.cloud
44 | spring-cloud-starter-eureka
45 |
46 |
47 | com.zhouq
48 | pay-api
49 | 0.0.1-SNAPSHOT
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/wms-service/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | com.zhouq
6 | wms-service
7 | 0.0.1-SNAPSHOT
8 | jar
9 |
10 | wms-service
11 | http://maven.apache.org
12 |
13 |
14 | UTF-8
15 | 1.8
16 | 1.8
17 |
18 |
19 |
20 | org.springframework.boot
21 | spring-boot-starter-parent
22 | 1.5.13.RELEASE
23 |
24 |
25 |
26 |
27 |
28 | org.springframework.cloud
29 | spring-cloud-dependencies
30 | Edgware.SR3
31 | pom
32 | import
33 |
34 |
35 |
36 |
37 |
38 |
39 | org.springframework.cloud
40 | spring-cloud-starter-config
41 |
42 |
43 | org.springframework.cloud
44 | spring-cloud-starter-eureka
45 |
46 |
47 | com.zhouq
48 | wms-api
49 | 0.0.1-SNAPSHOT
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/credit-service/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | com.zhouq
7 | credit-service
8 | 0.0.1-SNAPSHOT
9 |
10 | credit-service
11 | http://maven.apache.org
12 |
13 |
14 | UTF-8
15 | 1.8
16 | 1.8
17 |
18 |
19 |
20 | org.springframework.boot
21 | spring-boot-starter-parent
22 | 1.5.13.RELEASE
23 |
24 |
25 |
26 |
27 |
28 | org.springframework.cloud
29 | spring-cloud-dependencies
30 | Edgware.SR3
31 | pom
32 | import
33 |
34 |
35 |
36 |
37 |
38 |
39 | org.springframework.cloud
40 | spring-cloud-starter-config
41 |
42 |
43 | org.springframework.cloud
44 | spring-cloud-starter-eureka
45 |
46 |
47 | com.zhouq
48 | credit-api
49 | 0.0.1-SNAPSHOT
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/inventory-service/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | com.zhouq
6 | inventory-service
7 | 0.0.1-SNAPSHOT
8 | jar
9 |
10 | inventory-service
11 | http://maven.apache.org
12 |
13 |
14 | UTF-8
15 | 1.8
16 | 1.8
17 |
18 |
19 |
20 | org.springframework.boot
21 | spring-boot-starter-parent
22 | 1.5.13.RELEASE
23 |
24 |
25 |
26 |
27 |
28 | org.springframework.cloud
29 | spring-cloud-dependencies
30 | Edgware.SR3
31 | pom
32 | import
33 |
34 |
35 |
36 |
37 |
38 |
39 | org.springframework.cloud
40 | spring-cloud-starter-config
41 |
42 |
43 | org.springframework.cloud
44 | spring-cloud-starter-eureka
45 |
46 |
47 | com.zhouq
48 | inventory-api
49 | 0.0.1-SNAPSHOT
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/eureka-server/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 1.5.13.RELEASE
9 |
10 |
11 | com.zhouq
12 | eureka-server
13 | 0.0.1-SNAPSHOT
14 | eureka-server
15 | Demo project for Spring Boot
16 |
17 |
18 | UTF-8
19 | 1.8
20 | 1.8
21 |
22 |
23 |
24 |
25 |
26 | org.springframework.cloud
27 | spring-cloud-dependencies
28 | Edgware.SR3
29 | pom
30 | import
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 | org.springframework.cloud
42 | spring-cloud-starter-eureka
43 |
44 |
45 | org.springframework.cloud
46 | spring-cloud-starter-eureka-server
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/zuul-gateway/src/main/java/com/zhouq/demo/zuul/gateway/GrayReleaseFilter.java:
--------------------------------------------------------------------------------
1 | package com.zhouq.demo.zuul.gateway;
2 |
3 | import com.netflix.zuul.ZuulFilter;
4 | import com.netflix.zuul.context.RequestContext;
5 | import io.jmnarloch.spring.cloud.ribbon.support.RibbonFilterContextHolder;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.context.annotation.Configuration;
8 |
9 | import javax.servlet.http.HttpServletRequest;
10 |
11 | import java.util.Map;
12 | import java.util.Random;
13 |
14 | import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_DECORATION_FILTER_ORDER;
15 | import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
16 |
17 | /**
18 | * Create by zhouq on 2019/8/11
19 | */
20 | @Configuration
21 | public class GrayReleaseFilter extends ZuulFilter {
22 |
23 | @Autowired
24 | private GrayReleaseConfigManager grayReleaseConfigManager;
25 |
26 | @Override
27 | public String filterType() {
28 | return PRE_TYPE;
29 | }
30 |
31 | @Override
32 | public int filterOrder() {
33 | return PRE_DECORATION_FILTER_ORDER - 1;
34 | }
35 |
36 | @Override
37 | public boolean shouldFilter() {
38 | RequestContext ctx = RequestContext.getCurrentContext();
39 | HttpServletRequest request = ctx.getRequest();
40 | String requestURI = request.getRequestURI();
41 |
42 | // http://localhost:9000/order/order?xxxx
43 |
44 | Map grayReleaseConfigs = grayReleaseConfigManager.getGrayReleaseConfigs();
45 |
46 | for (String path : grayReleaseConfigs.keySet()) {
47 | if (requestURI.contains(path)) {
48 | GrayReleaseConfig grayReleaseConfig = grayReleaseConfigs.get(path);
49 | if (grayReleaseConfig.getEnableGrayRelease() == 1) {
50 | System.out.println(grayReleaseConfig.getServiceId() + ":启用了灰度发布...");
51 | return true;
52 | }
53 | }
54 | }
55 | return false;
56 | }
57 |
58 | @Override
59 | public Object run() {
60 |
61 | Random random = new Random();
62 | int seed = random.nextInt(100);
63 |
64 | if (seed == 50) {
65 | RibbonFilterContextHolder.getCurrentContext().add("version", "new");
66 | } else {
67 | RibbonFilterContextHolder.getCurrentContext().add("version", "current");
68 | }
69 |
70 | return null;
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/zuul-gateway/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | com.zhouq.demo
6 | zuul-gateway
7 | 0.0.1-SNAPSHOT
8 | jar
9 |
10 | zuul-gateway
11 | http://maven.apache.org
12 |
13 |
14 | UTF-8
15 | 1.8
16 | 1.8
17 |
18 |
19 |
20 | org.springframework.boot
21 | spring-boot-starter-parent
22 | 1.5.13.RELEASE
23 |
24 |
25 |
26 |
27 |
28 | org.springframework.cloud
29 | spring-cloud-dependencies
30 | Edgware.SR3
31 | pom
32 | import
33 |
34 |
35 |
36 |
37 |
38 |
39 | org.springframework.cloud
40 | spring-cloud-starter-zuul
41 |
42 |
43 | org.apache.httpcomponents
44 | httpclient
45 |
46 |
47 | org.springframework.cloud
48 | spring-cloud-starter-config
49 |
50 |
51 | org.springframework.cloud
52 | spring-cloud-starter-eureka
53 |
54 |
55 | org.springframework.retry
56 | spring-retry
57 |
58 |
59 |
60 | mysql
61 | mysql-connector-java
62 |
63 |
64 |
65 | org.springframework.boot
66 | spring-boot-starter-jdbc
67 |
68 |
69 |
70 | io.jmnarloch
71 | ribbon-discovery-filter-spring-cloud-starter
72 | 2.1.0
73 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ### spring-cloud 学习项目
2 |
3 | 本项目是学习《中华石杉老师-21天互联网Java进阶面试训练营(分布式篇)》课程时自己整理的笔记和代码试验,希望对大家有所帮助。
4 | 课程质量是当前市面上最好的,没有之一。可以扫一个下面二维码加入
5 |
6 | 
7 |
8 | 也可以微信上从下面链接进去:[https://apppuKyPtrl1086.h5.xiaoeknow.com/content_page/eyJ0eXBlIjoiMyIsInJlc291cmNlX3R5cGUiOiI2IiwicmVzb3VyY2VfaWQiOiIiLCJwcm9kdWN0X2lkIjoicF81ZDMxMTBjM2MwZTlkX0ZubVRUdGo0IiwiYXBwX2lkIjoiYXBwcHVLeVB0cmwxMDg2Iiwic2hhcmVfdXNlcl9pZCI6InVfNWQyMjllMWNkZDY4MV8yV21sd1pzTWRLIiwic2hhcmVfdHlwZSI6NX0](https://apppuKyPtrl1086.h5.xiaoeknow.com/content_page/eyJ0eXBlIjoiMyIsInJlc291cmNlX3R5cGUiOiI2IiwicmVzb3VyY2VfaWQiOiIiLCJwcm9kdWN0X2lkIjoicF81ZDMxMTBjM2MwZTlkX0ZubVRUdGo0IiwiYXBwX2lkIjoiYXBwcHVLeVB0cmwxMDg2Iiwic2hhcmVfdXNlcl9pZCI6InVfNWQyMjllMWNkZDY4MV8yV21sd1pzTWRLIiwic2hhcmVfdHlwZSI6NX0)
9 |
10 |
11 | ### 如何运行项目
12 | 首先运行 Eureka 服务注册中心 eureka-server
13 |
14 | 然后依次运行 各服务 credit-service、inventory-service、wms-service、order-service
15 |
16 | #### 2019-08-08 更新
17 |
18 | 已加入 Zuul 网关,并结合数据库方式实现了动态路由功能。
19 |
20 | #### 2019-08-11 更新
21 |
22 | Zuul 二次开发,实现了灰度发布方案。
23 |
24 | #### 2019-08-19 更新
25 |
26 | 生产环境的超时重试配置
27 |
28 | Spring cloud 线上可能出现第一次超时的问题。生产环境优化点。
29 |
30 | 第一次启动,人家调用你的时候会出现 timeout 的情况。
31 |
32 | 引起的原因:
33 |
34 | 每个服务第一次被请求调用,回去初始化一个 Ribbon 的组件,初始化这些组件需要耗费一定的时间,所以很容易导致超时问题。
35 | 解决办法就是让服务启动的时候就直接初始化,不在第一次调用的时候初始化。
36 |
37 | 四个点的优化:
38 |
39 | 1、ribbon 开启启动直接初始化
40 |
41 | ```
42 | ribbon:
43 | eager-load:
44 | enabled: true
45 | ```
46 |
47 | 2、eureka server
48 |
49 | ```
50 | eureka:
51 | instance:
52 | hostname: localhost
53 | # 服务超过2 秒没有上报,就视为
54 | lease-expiration-duration-in-seconds: 2
55 | client:
56 | registerWithEureka: false
57 | fetchRegistry: false
58 | serviceUrl:
59 | defaultZone: http://localhost:8761/eureka/
60 | server:
61 | enableSelfPreservation: false
62 | # 缓存信息 100ms 同步一次
63 | response-cache-update-interval-ms: 100
64 | # 每隔多少秒去检查心跳 1秒
65 | eviction-interval-timer-in-ms: 1000
66 | ```
67 |
68 | 3、各服务的eureka client 配置
69 | ```
70 | eureka:
71 | instance:
72 | hostname: localhost
73 | client:
74 | serviceUrl:
75 | defaultZone: http://localhost:8761/eureka
76 | # 每隔一秒拉取一次
77 | registry-fetch-interval-seconds: 1
78 | # 向服务注册时间 一秒一次
79 | instance-info-replication-interval-seconds: 1
80 | ```
81 | 4、网关 zuul 中的 ribbon 全局配置 延长超时时间
82 |
83 | ```
84 | ribbon:
85 | ConnectTimeout: 3000
86 | ReadTimeout: 3000
87 | OkToRetryOnAllOperations: true
88 | MaxAutoRetries: 1
89 | MaxAutoRetriesNextServer: 1
90 | ```
91 |
92 | 中小型的系统,没必要直接开启hystrix,资源隔离、熔断、降级,如果你没有设计好一整套系统高可用的方案。
93 |
94 | zuul请求一个订单服务,超过1秒就认为超时了,此时会先重试一下订单服务这台机器,如果还是不行就重试一下订单服务的其他机器。
95 |
96 | 超时时间大于 上面的 ribbon 的超时时间就行了。
97 |
98 | ```$xslt
99 | hystrix:
100 | command:
101 | default:
102 | execution:
103 | isolation:
104 | thread:
105 | timeoutInMilliseconds: 10000
106 | ```
107 |
--------------------------------------------------------------------------------
/order-service/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | com.zhouq
6 | order-service
7 | 0.0.1-SNAPSHOT
8 | jar
9 |
10 | order-service
11 | http://maven.apache.org
12 |
13 |
14 | UTF-8
15 | 1.8
16 | 1.8
17 |
18 |
19 |
20 | org.springframework.boot
21 | spring-boot-starter-parent
22 | 1.5.13.RELEASE
23 |
24 |
25 |
26 |
27 |
28 | org.springframework.cloud
29 | spring-cloud-dependencies
30 | Edgware.SR3
31 | pom
32 | import
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 | org.springframework.cloud
44 | spring-cloud-starter-eureka
45 |
46 |
47 | org.springframework.cloud
48 | spring-cloud-starter-ribbon
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.boot
60 | spring-boot-starter-actuator
61 |
62 |
63 | com.zhouq
64 | inventory-api
65 | 0.0.1-SNAPSHOT
66 |
67 |
68 | com.zhouq
69 | wms-api
70 | 0.0.1-SNAPSHOT
71 |
72 |
73 | com.zhouq
74 | credit-api
75 | 0.0.1-SNAPSHOT
76 |
77 |
78 | com.zhouq
79 | pay-api
80 | 0.0.1-SNAPSHOT
81 |
82 |
83 |
84 |
--------------------------------------------------------------------------------
/zuul-gateway/src/main/java/com/zhouq/demo/zuul/gateway/DynamicRouteLocator.java:
--------------------------------------------------------------------------------
1 | package com.zhouq.demo.zuul.gateway;
2 |
3 | import org.springframework.beans.BeanUtils;
4 | import org.springframework.cloud.netflix.zuul.filters.RefreshableRouteLocator;
5 | import org.springframework.cloud.netflix.zuul.filters.SimpleRouteLocator;
6 | import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
7 | import org.springframework.jdbc.core.BeanPropertyRowMapper;
8 | import org.springframework.jdbc.core.JdbcTemplate;
9 | import org.springframework.util.StringUtils;
10 |
11 | import java.util.LinkedHashMap;
12 | import java.util.List;
13 | import java.util.Map;
14 |
15 | /**
16 | * Create by zhouq on 2019/8/8
17 | */
18 | public class DynamicRouteLocator extends SimpleRouteLocator implements RefreshableRouteLocator {
19 |
20 | private JdbcTemplate jdbcTemplate;
21 |
22 | private ZuulProperties properties;
23 |
24 | public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
25 | this.jdbcTemplate = jdbcTemplate;
26 | }
27 |
28 | public void setProperties(ZuulProperties properties) {
29 | this.properties = properties;
30 | }
31 |
32 | public DynamicRouteLocator(String servletPath, ZuulProperties properties) {
33 | super(servletPath, properties);
34 | this.properties = properties;
35 | }
36 |
37 | @Override
38 | public void refresh() {
39 | System.out.println("------refresh----------");
40 | doRefresh();
41 | }
42 |
43 | @Override
44 | protected Map locateRoutes() {
45 | Map routesMap = new LinkedHashMap<>();
46 | //先加载本地
47 | routesMap.putAll(super.locateRoutes());
48 | routesMap.putAll(locateRoutesFormDB());
49 |
50 | // 统一处理一下路由path的格式
51 | LinkedHashMap values = new LinkedHashMap<>();
52 | for (Map.Entry entry : routesMap.entrySet()) {
53 | String path = entry.getKey();
54 | if (!path.startsWith("/")) {
55 | path = "/" + path;
56 | }
57 | if (StringUtils.hasText(this.properties.getPrefix())) {
58 | path = this.properties.getPrefix() + path;
59 | if (!path.startsWith("/")) {
60 | path = "/" + path;
61 | }
62 | }
63 | values.put(path, entry.getValue());
64 | }
65 |
66 | System.out.println("路由表:" + values);
67 | return values;
68 | }
69 |
70 | private Map locateRoutesFormDB() {
71 | Map routes = new LinkedHashMap<>();
72 |
73 | //读取数据库中的路由配置
74 | List results = jdbcTemplate.query(
75 | "select * from gateway_api_route where enabled = true",
76 | new BeanPropertyRowMapper<>(GatewayApiRoute.class)
77 | );
78 |
79 | for (GatewayApiRoute result : results) {
80 | if (StringUtils.isEmpty(result.getPath())) {
81 | continue;
82 | }
83 | if (StringUtils.isEmpty(result.getServiceId()) && StringUtils.isEmpty(result.getUrl())) {
84 | continue;
85 | }
86 |
87 | ZuulProperties.ZuulRoute zuulRoute = new ZuulProperties.ZuulRoute();
88 |
89 | try {
90 | BeanUtils.copyProperties(result, zuulRoute);
91 | } catch (Exception e) {
92 | e.printStackTrace();
93 | }
94 |
95 | routes.put(zuulRoute.getPath(), zuulRoute);
96 | }
97 | return routes;
98 | }
99 | }
100 |
--------------------------------------------------------------------------------