├── .gitignore ├── springcloud101-userservice-server ├── src │ └── main │ │ ├── java │ │ └── me │ │ │ └── josephzhu │ │ │ └── springcloud101 │ │ │ └── userservice │ │ │ └── server │ │ │ ├── UserRepository.java │ │ │ ├── UserEntity.java │ │ │ ├── UserServiceApplication.java │ │ │ └── UserServiceController.java │ │ └── resources │ │ └── application.properties └── pom.xml ├── springcloud101-projectservice-server ├── src │ └── main │ │ ├── java │ │ └── me │ │ │ └── josephzhu │ │ │ └── springcloud101 │ │ │ └── projectservice │ │ │ └── server │ │ │ ├── ProjectRepository.java │ │ │ ├── ProjectServiceApplication.java │ │ │ ├── ProjectEntity.java │ │ │ ├── RemoteUserService.java │ │ │ └── ProjectServiceController.java │ │ └── resources │ │ └── application.yml └── pom.xml ├── springcloud101-projectservice-listener ├── src │ └── main │ │ ├── java │ │ └── me.josephzhu.springcloud101.projectservice.listener │ │ │ ├── RemoteInvestService.java │ │ │ ├── ProjectServiceListenerApplication.java │ │ │ ├── RemoteProjectService.java │ │ │ ├── RemoteUserService.java │ │ │ └── ProjectServiceListener.java │ │ └── resources │ │ └── application.yml └── pom.xml ├── springcloud101-investservice-server ├── src │ └── main │ │ ├── java │ │ └── me │ │ │ └── josephzhu │ │ │ └── springcloud101 │ │ │ └── investservice │ │ │ └── server │ │ │ ├── InvestRepository.java │ │ │ ├── InvestEntity.java │ │ │ ├── RemoteProjectService.java │ │ │ ├── RemoteUserService.java │ │ │ ├── InvestServiceApplication.java │ │ │ └── InvestServiceController.java │ │ └── resources │ │ └── application.yml └── pom.xml ├── springcloud101-eureka-server ├── src │ └── main │ │ ├── resources │ │ └── application.yml │ │ └── java │ │ └── me │ │ └── josephzhu │ │ └── springcloud101 │ │ └── eurekaserver │ │ └── EurekaServerApplication.java └── pom.xml ├── springcloud101-admin-server ├── src │ └── main │ │ ├── resources │ │ └── application.yml │ │ └── java │ │ └── me │ │ └── josephzhu │ │ └── springcloud101 │ │ └── admin │ │ └── server │ │ └── AdminServerApplication.java └── pom.xml ├── springcloud101-userservice-api ├── src │ └── main │ │ └── java │ │ └── me │ │ └── josephzhu │ │ └── springcloud101 │ │ └── userservice │ │ └── api │ │ ├── User.java │ │ └── UserService.java └── pom.xml ├── springcloud101-zuul-server ├── src │ └── main │ │ ├── java │ │ └── me │ │ │ └── josephzhu │ │ │ └── springcloud101 │ │ │ └── zuul │ │ │ └── server │ │ │ ├── ZuulServerApplication.java │ │ │ └── TokenFilter.java │ │ └── resources │ │ └── application.yml └── pom.xml ├── springcloud101-turbine-server ├── src │ └── main │ │ ├── resources │ │ └── application.yml │ │ └── java │ │ └── me │ │ └── josephzhu │ │ └── springcloud101 │ │ └── turbine │ │ └── server │ │ └── TurbineServerApplication.java └── pom.xml ├── springcloud101-investservice-api ├── src │ └── main │ │ └── java │ │ └── me │ │ └── josephzhu │ │ └── springcloud101 │ │ └── investservice │ │ └── api │ │ ├── Invest.java │ │ └── InvestService.java └── pom.xml ├── springcloud101-projectservice-api ├── src │ └── main │ │ └── java │ │ └── me │ │ └── josephzhu │ │ └── springcloud101 │ │ └── projectservice │ │ └── api │ │ ├── Project.java │ │ └── ProjectService.java └── pom.xml ├── readme.md └── pom.xml /.gitignore: -------------------------------------------------------------------------------- 1 | */target 2 | .idea 3 | *.iml 4 | -------------------------------------------------------------------------------- /springcloud101-userservice-server/src/main/java/me/josephzhu/springcloud101/userservice/server/UserRepository.java: -------------------------------------------------------------------------------- 1 | package me.josephzhu.springcloud101.userservice.server; 2 | 3 | import org.springframework.data.repository.CrudRepository; 4 | 5 | public interface UserRepository extends CrudRepository { 6 | } 7 | -------------------------------------------------------------------------------- /springcloud101-projectservice-server/src/main/java/me/josephzhu/springcloud101/projectservice/server/ProjectRepository.java: -------------------------------------------------------------------------------- 1 | package me.josephzhu.springcloud101.projectservice.server; 2 | 3 | import org.springframework.data.repository.CrudRepository; 4 | 5 | public interface ProjectRepository extends CrudRepository { 6 | } 7 | -------------------------------------------------------------------------------- /springcloud101-projectservice-listener/src/main/java/me.josephzhu.springcloud101.projectservice.listener/RemoteInvestService.java: -------------------------------------------------------------------------------- 1 | package me.josephzhu.springcloud101.projectservice.listener; 2 | 3 | import me.josephzhu.springcloud101.investservice.api.InvestService; 4 | import org.springframework.cloud.openfeign.FeignClient; 5 | 6 | @FeignClient(value = "investservice") 7 | public interface RemoteInvestService extends InvestService { 8 | } 9 | -------------------------------------------------------------------------------- /springcloud101-investservice-server/src/main/java/me/josephzhu/springcloud101/investservice/server/InvestRepository.java: -------------------------------------------------------------------------------- 1 | package me.josephzhu.springcloud101.investservice.server; 2 | 3 | import org.springframework.data.repository.CrudRepository; 4 | 5 | import java.util.List; 6 | 7 | public interface InvestRepository extends CrudRepository { 8 | List findByProjectIdAndStatus(long projectId, int status); 9 | } 10 | -------------------------------------------------------------------------------- /springcloud101-eureka-server/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8865 3 | 4 | eureka: 5 | instance: 6 | hostname: localhost 7 | client: 8 | registry-fetch-interval-seconds: 5 9 | registerWithEureka: false 10 | fetchRegistry: false 11 | serviceUrl: 12 | defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ 13 | server: 14 | enable-self-preservation: true 15 | eviction-interval-timer-in-ms: 5000 16 | 17 | spring: 18 | application: 19 | name: eurka-server -------------------------------------------------------------------------------- /springcloud101-eureka-server/src/main/java/me/josephzhu/springcloud101/eurekaserver/EurekaServerApplication.java: -------------------------------------------------------------------------------- 1 | package me.josephzhu.springcloud101.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 | -------------------------------------------------------------------------------- /springcloud101-admin-server/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8868 3 | 4 | spring: 5 | application: 6 | name: adminserver 7 | zipkin: 8 | base-url: http://localhost:9411 9 | sleuth: 10 | feign: 11 | enabled: true 12 | sampler: 13 | probability: 1.0 14 | 15 | eureka: 16 | client: 17 | serviceUrl: 18 | defaultZone: http://localhost:8865/eureka/ 19 | registry-fetch-interval-seconds: 5 20 | 21 | management: 22 | endpoints: 23 | web: 24 | exposure: 25 | include: "*" 26 | 27 | endpoint: 28 | health: 29 | show-details: always 30 | -------------------------------------------------------------------------------- /springcloud101-userservice-api/src/main/java/me/josephzhu/springcloud101/userservice/api/User.java: -------------------------------------------------------------------------------- 1 | package me.josephzhu.springcloud101.userservice.api; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.math.BigDecimal; 9 | import java.util.Date; 10 | 11 | @Data 12 | @Builder 13 | @AllArgsConstructor 14 | @NoArgsConstructor 15 | public class User { 16 | private Long id; 17 | private String name; 18 | private BigDecimal availableBalance; 19 | private BigDecimal frozenBalance; 20 | private Date createdAt; 21 | } 22 | -------------------------------------------------------------------------------- /springcloud101-zuul-server/src/main/java/me/josephzhu/springcloud101/zuul/server/ZuulServerApplication.java: -------------------------------------------------------------------------------- 1 | package me.josephzhu.springcloud101.zuul.server; 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 | @EnableZuulProxy 10 | @EnableDiscoveryClient 11 | public class ZuulServerApplication { 12 | 13 | public static void main(String[] args) { 14 | SpringApplication.run( ZuulServerApplication.class, args ); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /springcloud101-admin-server/src/main/java/me/josephzhu/springcloud101/admin/server/AdminServerApplication.java: -------------------------------------------------------------------------------- 1 | package me.josephzhu.springcloud101.admin.server; 2 | 3 | import de.codecentric.boot.admin.server.config.EnableAdminServer; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 7 | 8 | @SpringBootApplication 9 | @EnableAdminServer 10 | @EnableDiscoveryClient 11 | public class AdminServerApplication { 12 | 13 | public static void main(String[] args) { 14 | SpringApplication.run( AdminServerApplication.class, args ); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /springcloud101-turbine-server/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8867 3 | 4 | spring: 5 | application: 6 | name: turbineserver 7 | 8 | eureka: 9 | client: 10 | serviceUrl: 11 | defaultZone: http://localhost:8865/eureka/ 12 | 13 | management: 14 | endpoints: 15 | web: 16 | exposure: 17 | include: "*" 18 | 19 | endpoint: 20 | health: 21 | show-details: always 22 | 23 | turbine: 24 | aggregator: 25 | clusterConfig: default 26 | clusterNameExpression: "'default'" 27 | combine-host: true 28 | instanceUrlSuffix: 29 | default: actuator/hystrix.stream 30 | app-config: investservice,userservice,projectservice,projectservice-listener -------------------------------------------------------------------------------- /springcloud101-investservice-api/src/main/java/me/josephzhu/springcloud101/investservice/api/Invest.java: -------------------------------------------------------------------------------- 1 | package me.josephzhu.springcloud101.investservice.api; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.math.BigDecimal; 9 | import java.util.Date; 10 | 11 | @Data 12 | @Builder 13 | @AllArgsConstructor 14 | @NoArgsConstructor 15 | public class Invest { 16 | private Long id; 17 | private long investorId; 18 | private long borrowerId; 19 | private long projectId; 20 | private int status; 21 | private BigDecimal amount; 22 | private Date createdAt; 23 | private Date updatedAt; 24 | } 25 | -------------------------------------------------------------------------------- /springcloud101-projectservice-api/src/main/java/me/josephzhu/springcloud101/projectservice/api/Project.java: -------------------------------------------------------------------------------- 1 | package me.josephzhu.springcloud101.projectservice.api; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.math.BigDecimal; 9 | import java.util.Date; 10 | 11 | @Data 12 | @Builder 13 | @NoArgsConstructor 14 | @AllArgsConstructor 15 | public class Project { 16 | private Long id; 17 | private BigDecimal totalAmount; 18 | private BigDecimal remainAmount; 19 | private String name; 20 | private String reason; 21 | private long borrowerId; 22 | private String borrowerName; 23 | private int status; 24 | private Date createdAt; 25 | } 26 | -------------------------------------------------------------------------------- /springcloud101-projectservice-listener/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8764 3 | 4 | spring: 5 | application: 6 | name: projectservice-listener 7 | cloud: 8 | stream: 9 | bindings: 10 | input: 11 | destination: zhuye 12 | zipkin: 13 | base-url: http://localhost:9411 14 | sleuth: 15 | feign: 16 | enabled: true 17 | sampler: 18 | probability: 1.0 19 | 20 | feign: 21 | hystrix: 22 | enabled: true 23 | 24 | eureka: 25 | client: 26 | serviceUrl: 27 | defaultZone: http://localhost:8865/eureka/ 28 | registry-fetch-interval-seconds: 5 29 | 30 | management: 31 | endpoints: 32 | web: 33 | exposure: 34 | include: "*" 35 | endpoint: 36 | health: 37 | show-details: always -------------------------------------------------------------------------------- /springcloud101-investservice-api/src/main/java/me/josephzhu/springcloud101/investservice/api/InvestService.java: -------------------------------------------------------------------------------- 1 | package me.josephzhu.springcloud101.investservice.api; 2 | 3 | import org.springframework.web.bind.annotation.GetMapping; 4 | import org.springframework.web.bind.annotation.PostMapping; 5 | import org.springframework.web.bind.annotation.RequestParam; 6 | 7 | import java.math.BigDecimal; 8 | import java.util.List; 9 | 10 | public interface InvestService { 11 | @PostMapping("createInvest") 12 | Invest createOrder(@RequestParam("userId") long userId, 13 | @RequestParam("projectId") long projectId, 14 | @RequestParam("amount") BigDecimal amount) throws Exception; 15 | @GetMapping("getOrders") 16 | List getOrders(@RequestParam("projectId") long projectId) throws Exception; 17 | } 18 | -------------------------------------------------------------------------------- /springcloud101-userservice-api/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | springcloud101 7 | me.josephzhu 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | springcloud101-userservice-api 13 | 14 | 15 | 16 | org.springframework.cloud 17 | spring-cloud-starter-openfeign 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /springcloud101-eureka-server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | springcloud101 7 | me.josephzhu 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | springcloud101-eureka-server 13 | 14 | 15 | 16 | org.springframework.cloud 17 | spring-cloud-starter-netflix-eureka-server 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /springcloud101-investservice-api/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | springcloud101 7 | me.josephzhu 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | springcloud101-investservice-api 13 | 14 | 15 | 16 | org.springframework.cloud 17 | spring-cloud-starter-openfeign 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /springcloud101-projectservice-api/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | springcloud101 7 | me.josephzhu 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | springcloud101-projectservice-api 13 | 14 | 15 | 16 | org.springframework.cloud 17 | spring-cloud-starter-openfeign 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /springcloud101-projectservice-api/src/main/java/me/josephzhu/springcloud101/projectservice/api/ProjectService.java: -------------------------------------------------------------------------------- 1 | package me.josephzhu.springcloud101.projectservice.api; 2 | 3 | import org.springframework.web.bind.annotation.GetMapping; 4 | import org.springframework.web.bind.annotation.PostMapping; 5 | import org.springframework.web.bind.annotation.RequestParam; 6 | 7 | import java.math.BigDecimal; 8 | 9 | public interface ProjectService { 10 | @GetMapping("getProject") 11 | Project getProject(@RequestParam("id") long id) throws Exception; 12 | @PostMapping("gotInvested") 13 | BigDecimal gotInvested(@RequestParam("id") long id, 14 | @RequestParam("amount") BigDecimal amount) throws Exception; 15 | @PostMapping("lendpay") 16 | BigDecimal lendpay(@RequestParam("id") long id) throws Exception; 17 | } 18 | -------------------------------------------------------------------------------- /springcloud101-userservice-server/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.port=8761 2 | spring.application.name=userservice 3 | spring.datasource.url=jdbc:mysql://localhost:3306/p2p?useSSL=false 4 | spring.datasource.username=root 5 | spring.datasource.password=root 6 | spring.datasource.driver-class-name=com.mysql.jdbc.Driver 7 | spring.zipkin.base-url=http://localhost:9411 8 | spring.sleuth.feign.enabled=true 9 | spring.sleuth.sampler.probability=1.0 10 | spring.jpa.show-sql=true 11 | spring.jpa.hibernate.use-new-id-generator-mappings=false 12 | spring.redis.host=localhost 13 | spring.redis.pool=6379 14 | feign.hystrix.enabled=true 15 | eureka.client.serviceUrl.defaultZone=http://localhost:8865/eureka/ 16 | eureka.client.registry-fetch-interval-seconds=5 17 | management.endpoints.web.exposure.include=* 18 | management.endpoint.health.show-details=always 19 | -------------------------------------------------------------------------------- /springcloud101-userservice-server/src/main/java/me/josephzhu/springcloud101/userservice/server/UserEntity.java: -------------------------------------------------------------------------------- 1 | package me.josephzhu.springcloud101.userservice.server; 2 | 3 | import lombok.Data; 4 | import org.springframework.data.annotation.CreatedDate; 5 | import org.springframework.data.annotation.LastModifiedDate; 6 | import org.springframework.data.jpa.domain.support.AuditingEntityListener; 7 | 8 | import javax.persistence.*; 9 | import java.math.BigDecimal; 10 | import java.util.Date; 11 | 12 | @Data 13 | @Entity 14 | @Table(name = "user") 15 | @EntityListeners(AuditingEntityListener.class) 16 | public class UserEntity { 17 | @Id 18 | @GeneratedValue 19 | private Long id; 20 | private String name; 21 | private BigDecimal availableBalance; 22 | private BigDecimal frozenBalance; 23 | @CreatedDate 24 | private Date createdAt; 25 | @LastModifiedDate 26 | private Date updatedAt; 27 | } 28 | -------------------------------------------------------------------------------- /springcloud101-investservice-server/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8763 3 | 4 | spring: 5 | application: 6 | name: investservice 7 | datasource: 8 | url: jdbc:mysql://localhost:3306/p2p?useSSL=false 9 | username: root 10 | password: root 11 | driver-class-name: com.mysql.jdbc.Driver 12 | zipkin: 13 | base-url: http://localhost:9411 14 | sleuth: 15 | feign: 16 | enabled: true 17 | sampler: 18 | probability: 1.0 19 | jpa: 20 | show-sql: true 21 | hibernate: 22 | use-new-id-generator-mappings: false 23 | feign: 24 | hystrix: 25 | enabled: true 26 | 27 | eureka: 28 | client: 29 | serviceUrl: 30 | defaultZone: http://localhost:8865/eureka/ 31 | registry-fetch-interval-seconds: 5 32 | 33 | 34 | management: 35 | endpoints: 36 | web: 37 | exposure: 38 | include: "*" 39 | endpoint: 40 | health: 41 | show-details: always 42 | -------------------------------------------------------------------------------- /springcloud101-projectservice-listener/src/main/java/me.josephzhu.springcloud101.projectservice.listener/ProjectServiceListenerApplication.java: -------------------------------------------------------------------------------- 1 | package me.josephzhu.springcloud101.projectservice.listener; 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.hystrix.EnableHystrix; 8 | import org.springframework.cloud.openfeign.EnableFeignClients; 9 | 10 | @SpringBootApplication 11 | @EnableDiscoveryClient 12 | @EnableFeignClients 13 | @EnableHystrix 14 | @EnableCircuitBreaker 15 | public class ProjectServiceListenerApplication { 16 | public static void main(String[] args) { 17 | SpringApplication.run( ProjectServiceListenerApplication.class, args ); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /springcloud101-zuul-server/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8866 3 | 4 | spring: 5 | application: 6 | name: zuulserver 7 | zipkin: 8 | base-url: http://localhost:9411 9 | sleuth: 10 | feign: 11 | enabled: true 12 | sampler: 13 | probability: 1.0 14 | 15 | eureka: 16 | client: 17 | serviceUrl: 18 | defaultZone: http://localhost:8865/eureka/ 19 | registry-fetch-interval-seconds: 5 20 | 21 | zuul: 22 | routes: 23 | invest: 24 | path: /invest/** 25 | serviceId: investservice 26 | user: 27 | path: /user/** 28 | serviceId: userservice 29 | project: 30 | path: /project/** 31 | serviceId: projectservice 32 | host: 33 | socket-timeout-millis: 60000 34 | connect-timeout-millis: 60000 35 | 36 | 37 | management: 38 | endpoints: 39 | web: 40 | exposure: 41 | include: "*" 42 | 43 | endpoint: 44 | health: 45 | show-details: always 46 | -------------------------------------------------------------------------------- /springcloud101-userservice-api/src/main/java/me/josephzhu/springcloud101/userservice/api/UserService.java: -------------------------------------------------------------------------------- 1 | package me.josephzhu.springcloud101.userservice.api; 2 | 3 | import org.springframework.web.bind.annotation.GetMapping; 4 | import org.springframework.web.bind.annotation.PostMapping; 5 | import org.springframework.web.bind.annotation.RequestParam; 6 | 7 | import java.math.BigDecimal; 8 | 9 | public interface UserService { 10 | @GetMapping("getUser") 11 | User getUser(@RequestParam("id") long id) throws Exception; 12 | @PostMapping("consumeMoney") 13 | BigDecimal consumeMoney(@RequestParam("investorId") long investorId, 14 | @RequestParam("amount") BigDecimal amount) throws Exception; 15 | @PostMapping("lendpayMoney") 16 | BigDecimal lendpayMoney(@RequestParam("investorId") long investorId, 17 | @RequestParam("borrowerId") long borrowerId, 18 | @RequestParam("amount") BigDecimal amount) throws Exception; 19 | } 20 | -------------------------------------------------------------------------------- /springcloud101-projectservice-server/src/main/java/me/josephzhu/springcloud101/projectservice/server/ProjectServiceApplication.java: -------------------------------------------------------------------------------- 1 | package me.josephzhu.springcloud101.projectservice.server; 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.hystrix.EnableHystrix; 8 | import org.springframework.cloud.openfeign.EnableFeignClients; 9 | import org.springframework.data.jpa.repository.config.EnableJpaAuditing; 10 | 11 | @SpringBootApplication 12 | @EnableDiscoveryClient 13 | @EnableFeignClients 14 | @EnableJpaAuditing 15 | @EnableHystrix 16 | @EnableCircuitBreaker 17 | public class ProjectServiceApplication { 18 | public static void main(String[] args) { 19 | SpringApplication.run( ProjectServiceApplication.class, args ); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /springcloud101-projectservice-server/src/main/java/me/josephzhu/springcloud101/projectservice/server/ProjectEntity.java: -------------------------------------------------------------------------------- 1 | package me.josephzhu.springcloud101.projectservice.server; 2 | 3 | import lombok.Data; 4 | import org.springframework.data.annotation.CreatedDate; 5 | import org.springframework.data.annotation.LastModifiedDate; 6 | import org.springframework.data.jpa.domain.support.AuditingEntityListener; 7 | 8 | import javax.persistence.*; 9 | import java.math.BigDecimal; 10 | import java.util.Date; 11 | 12 | @Data 13 | @Entity 14 | @Table(name = "project") 15 | @EntityListeners(AuditingEntityListener.class) 16 | public class ProjectEntity { 17 | @Id 18 | @GeneratedValue 19 | private Long id; 20 | private BigDecimal totalAmount; 21 | private BigDecimal remainAmount; 22 | private String name; 23 | private String reason; 24 | private long borrowerId; 25 | private int status; 26 | @CreatedDate 27 | private Date createdAt; 28 | @LastModifiedDate 29 | private Date updatedAt; 30 | } 31 | -------------------------------------------------------------------------------- /springcloud101-projectservice-server/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8762 3 | 4 | spring: 5 | application: 6 | name: projectservice 7 | cloud: 8 | stream: 9 | bindings: 10 | output: 11 | destination: zhuye 12 | datasource: 13 | url: jdbc:mysql://localhost:3306/p2p?useSSL=false 14 | username: root 15 | password: root 16 | driver-class-name: com.mysql.jdbc.Driver 17 | zipkin: 18 | base-url: http://localhost:9411 19 | sleuth: 20 | feign: 21 | enabled: true 22 | sampler: 23 | probability: 1.0 24 | jpa: 25 | show-sql: true 26 | hibernate: 27 | use-new-id-generator-mappings: false 28 | feign: 29 | hystrix: 30 | enabled: true 31 | 32 | eureka: 33 | client: 34 | serviceUrl: 35 | defaultZone: http://localhost:8865/eureka/ 36 | registry-fetch-interval-seconds: 5 37 | 38 | 39 | management: 40 | endpoints: 41 | web: 42 | exposure: 43 | include: "*" 44 | endpoint: 45 | health: 46 | show-details: always 47 | -------------------------------------------------------------------------------- /springcloud101-turbine-server/src/main/java/me/josephzhu/springcloud101/turbine/server/TurbineServerApplication.java: -------------------------------------------------------------------------------- 1 | package me.josephzhu.springcloud101.turbine.server; 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.eureka.EnableEurekaClient; 8 | import org.springframework.cloud.netflix.hystrix.EnableHystrix; 9 | import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard; 10 | import org.springframework.cloud.netflix.turbine.EnableTurbine; 11 | 12 | @SpringBootApplication 13 | @EnableDiscoveryClient 14 | @EnableHystrix 15 | @EnableHystrixDashboard 16 | @EnableCircuitBreaker 17 | @EnableTurbine 18 | public class TurbineServerApplication { 19 | 20 | public static void main(String[] args) { 21 | SpringApplication.run( TurbineServerApplication.class, args ); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /springcloud101-investservice-server/src/main/java/me/josephzhu/springcloud101/investservice/server/InvestEntity.java: -------------------------------------------------------------------------------- 1 | package me.josephzhu.springcloud101.investservice.server; 2 | 3 | import lombok.Data; 4 | import org.springframework.data.annotation.CreatedDate; 5 | import org.springframework.data.annotation.LastModifiedDate; 6 | import org.springframework.data.jpa.domain.support.AuditingEntityListener; 7 | 8 | import javax.persistence.*; 9 | import java.math.BigDecimal; 10 | import java.util.Date; 11 | 12 | @Data 13 | @Entity 14 | @Table(name = "invest") 15 | @EntityListeners(AuditingEntityListener.class) 16 | public class InvestEntity { 17 | @Id 18 | @GeneratedValue 19 | private Long id; 20 | private long investorId; 21 | private long borrowerId; 22 | private long projectId; 23 | private String investorName; 24 | private String borrowerName; 25 | private String projectName; 26 | private BigDecimal amount; 27 | private int status; 28 | @CreatedDate 29 | private Date createdAt; 30 | @LastModifiedDate 31 | private Date updatedAt; 32 | } 33 | -------------------------------------------------------------------------------- /springcloud101-investservice-server/src/main/java/me/josephzhu/springcloud101/investservice/server/RemoteProjectService.java: -------------------------------------------------------------------------------- 1 | package me.josephzhu.springcloud101.investservice.server; 2 | 3 | import me.josephzhu.springcloud101.projectservice.api.Project; 4 | import me.josephzhu.springcloud101.projectservice.api.ProjectService; 5 | import org.springframework.cloud.openfeign.FeignClient; 6 | import org.springframework.stereotype.Component; 7 | 8 | import java.math.BigDecimal; 9 | 10 | @FeignClient(value = "projectservice", fallback = RemoteProjectService.Fallback.class) 11 | public interface RemoteProjectService extends ProjectService { 12 | @Component 13 | class Fallback implements RemoteProjectService { 14 | 15 | @Override 16 | public Project getProject(long id) throws Exception { 17 | return null; 18 | } 19 | 20 | @Override 21 | public BigDecimal gotInvested(long id, BigDecimal amount) throws Exception { 22 | return null; 23 | } 24 | 25 | @Override 26 | public BigDecimal lendpay(long id) throws Exception { 27 | return null; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /springcloud101-projectservice-listener/src/main/java/me.josephzhu.springcloud101.projectservice.listener/RemoteProjectService.java: -------------------------------------------------------------------------------- 1 | package me.josephzhu.springcloud101.projectservice.listener; 2 | 3 | import me.josephzhu.springcloud101.projectservice.api.Project; 4 | import me.josephzhu.springcloud101.projectservice.api.ProjectService; 5 | import org.springframework.cloud.openfeign.FeignClient; 6 | import org.springframework.stereotype.Component; 7 | 8 | import java.math.BigDecimal; 9 | 10 | @FeignClient(value = "projectservice", fallback = RemoteProjectService.Fallback.class) 11 | public interface RemoteProjectService extends ProjectService { 12 | @Component 13 | class Fallback implements RemoteProjectService { 14 | 15 | @Override 16 | public Project getProject(long id) throws Exception { 17 | return null; 18 | } 19 | 20 | @Override 21 | public BigDecimal gotInvested(long id, BigDecimal amount) throws Exception { 22 | return null; 23 | } 24 | 25 | @Override 26 | public BigDecimal lendpay(long id) throws Exception { 27 | return null; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /springcloud101-projectservice-server/src/main/java/me/josephzhu/springcloud101/projectservice/server/RemoteUserService.java: -------------------------------------------------------------------------------- 1 | package me.josephzhu.springcloud101.projectservice.server; 2 | 3 | import me.josephzhu.springcloud101.userservice.api.User; 4 | import me.josephzhu.springcloud101.userservice.api.UserService; 5 | import org.springframework.cloud.openfeign.FeignClient; 6 | import org.springframework.stereotype.Component; 7 | 8 | import java.math.BigDecimal; 9 | 10 | @FeignClient(value = "userservice",fallback = RemoteUserService.Fallback.class) 11 | public interface RemoteUserService extends UserService { 12 | @Component 13 | class Fallback implements RemoteUserService { 14 | 15 | @Override 16 | public User getUser(long id) throws Exception { 17 | return null; 18 | } 19 | 20 | @Override 21 | public BigDecimal consumeMoney(long id, BigDecimal amount) throws Exception { 22 | return null; 23 | } 24 | 25 | @Override 26 | public BigDecimal lendpayMoney(long investorId, long borrowerId, BigDecimal amount) throws Exception { 27 | return null; 28 | } 29 | } 30 | } 31 | 32 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | 本文会以一个简单而完整的业务来阐述Spring Cloud Finchley.RELEASE版本常用组件的使用。如下图所示,本文会覆盖的组件有: 2 | 1. Spring Cloud Netflix Zuul网关服务器 3 | 2. Spring Cloud Netflix Eureka发现服务器 4 | 3. Spring Cloud Netflix Turbine断路器监控 5 | 4. Spring Cloud Sleuth + Zipkin服务调用监控 6 | 5. Sping Cloud Stream + RabbitMQ做异步消息 7 | 6. Spring Data JPA做数据访问 8 | 9 | 本文的例子使用的依赖版本是: 10 | 1. Spring Cloud - Finchley.RELEASE 11 | 2. Spring Data - Lovelace-RELEASE 12 | 3. Spring Cloud Stream - Fishtown.M3 13 | 4. Spring Boot - 2.0.5.RELEASE 14 | 15 | 各项组件详细使用请参见官网,Spring组件版本变化差异较大,网上代码复制粘贴不一定能够适用,最最好的资料来源只有官网+阅读源代码,直接给出地址方便你阅读本文的时候阅读官网的文档: 16 | 1. 全链路监控:http://cloud.spring.io/spring-cloud-static/spring-cloud-sleuth/2.0.1.RELEASE/single/spring-cloud-sleuth.html 17 | 2. 服务发现、网关、断路器:http://cloud.spring.io/spring-cloud-static/spring-cloud-netflix/2.0.1.RELEASE/single/spring-cloud-netflix.html 18 | 3. 服务调用:http://cloud.spring.io/spring-cloud-static/spring-cloud-openfeign/2.0.1.RELEASE/single/spring-cloud-openfeign.html 19 | 4. 异步消息:https://docs.spring.io/spring-cloud-stream/docs/Fishtown.M3/reference/htmlsingle/ 20 | 5. 数据访问:https://docs.spring.io/spring-data/jpa/docs/2.1.0.RELEASE/reference/html/ 21 | 22 | 完整文章见 https://juejin.im/post/5bc013f45188255c3050156b 23 | 24 | -------------------------------------------------------------------------------- /springcloud101-userservice-server/src/main/java/me/josephzhu/springcloud101/userservice/server/UserServiceApplication.java: -------------------------------------------------------------------------------- 1 | package me.josephzhu.springcloud101.userservice.server; 2 | 3 | import org.redisson.Redisson; 4 | import org.redisson.api.RedissonClient; 5 | import org.springframework.boot.SpringApplication; 6 | import org.springframework.boot.autoconfigure.SpringBootApplication; 7 | import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; 8 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 9 | import org.springframework.cloud.netflix.hystrix.EnableHystrix; 10 | import org.springframework.context.annotation.Bean; 11 | import org.springframework.context.annotation.Configuration; 12 | import org.springframework.data.jpa.repository.config.EnableJpaAuditing; 13 | 14 | @SpringBootApplication 15 | @EnableDiscoveryClient 16 | @EnableJpaAuditing 17 | @EnableHystrix 18 | @EnableCircuitBreaker 19 | @Configuration 20 | public class UserServiceApplication { 21 | @Bean 22 | RedissonClient redissonClient() { 23 | return Redisson.create(); 24 | } 25 | public static void main(String[] args) { 26 | SpringApplication.run( UserServiceApplication.class, args ); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /springcloud101-investservice-server/src/main/java/me/josephzhu/springcloud101/investservice/server/RemoteUserService.java: -------------------------------------------------------------------------------- 1 | package me.josephzhu.springcloud101.investservice.server; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import me.josephzhu.springcloud101.userservice.api.User; 5 | import me.josephzhu.springcloud101.userservice.api.UserService; 6 | import org.springframework.cloud.openfeign.FeignClient; 7 | import org.springframework.stereotype.Component; 8 | 9 | import java.math.BigDecimal; 10 | 11 | @FeignClient(value = "userservice", fallback = RemoteUserService.Fallback.class) 12 | public interface RemoteUserService extends UserService { 13 | @Component 14 | @Slf4j 15 | class Fallback implements RemoteUserService { 16 | 17 | @Override 18 | public User getUser(long id) throws Exception { 19 | log.warn("getUser fallback"); 20 | return null; 21 | } 22 | 23 | @Override 24 | public BigDecimal consumeMoney(long id, BigDecimal amount) throws Exception { 25 | log.warn("consumeMoney fallback"); 26 | return null; 27 | } 28 | 29 | @Override 30 | public BigDecimal lendpayMoney(long investorId, long borrowerId, BigDecimal amount) throws Exception { 31 | log.warn("lendpayMoney fallback"); 32 | return null; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /springcloud101-projectservice-listener/src/main/java/me.josephzhu.springcloud101.projectservice.listener/RemoteUserService.java: -------------------------------------------------------------------------------- 1 | package me.josephzhu.springcloud101.projectservice.listener; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import me.josephzhu.springcloud101.userservice.api.User; 5 | import me.josephzhu.springcloud101.userservice.api.UserService; 6 | import org.springframework.cloud.openfeign.FeignClient; 7 | import org.springframework.stereotype.Component; 8 | 9 | import java.math.BigDecimal; 10 | 11 | @FeignClient(value = "userservice", fallback = RemoteUserService.Fallback.class) 12 | public interface RemoteUserService extends UserService { 13 | @Component 14 | @Slf4j 15 | class Fallback implements RemoteUserService { 16 | 17 | @Override 18 | public User getUser(long id) throws Exception { 19 | log.warn("getUser fallback"); 20 | return null; 21 | } 22 | 23 | @Override 24 | public BigDecimal consumeMoney(long id, BigDecimal amount) throws Exception { 25 | log.warn("consumeMoney fallback"); 26 | return null; 27 | } 28 | 29 | @Override 30 | public BigDecimal lendpayMoney(long investorId, long borrowerId, BigDecimal amount) throws Exception { 31 | log.warn("lendpayMoney fallback"); 32 | return null; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /springcloud101-admin-server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | springcloud101 7 | me.josephzhu 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | springcloud101-admin-server 13 | 14 | 15 | 16 | de.codecentric 17 | spring-boot-admin-starter-server 18 | 2.0.3 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter-web 23 | 24 | 25 | org.springframework.cloud 26 | spring-cloud-starter-netflix-eureka-client 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-webflux 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /springcloud101-zuul-server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | springcloud101 7 | me.josephzhu 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | springcloud101-zuul-server 13 | 14 | 15 | 16 | org.springframework.cloud 17 | spring-cloud-starter-netflix-eureka-client 18 | 19 | 20 | org.springframework.cloud 21 | spring-cloud-starter-netflix-zuul 22 | 23 | 24 | org.springframework.boot 25 | spring-boot-starter-actuator 26 | 27 | 28 | org.springframework.cloud 29 | spring-cloud-starter-sleuth 30 | 31 | 32 | org.springframework.cloud 33 | spring-cloud-starter-zipkin 34 | 35 | 36 | -------------------------------------------------------------------------------- /springcloud101-turbine-server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | springcloud101 7 | me.josephzhu 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | springcloud101-turbine-server 13 | 14 | 15 | 16 | org.springframework.cloud 17 | spring-cloud-starter-netflix-eureka-client 18 | 19 | 20 | org.springframework.boot 21 | spring-boot-starter-actuator 22 | 23 | 24 | org.springframework.cloud 25 | spring-cloud-starter-netflix-hystrix 26 | 27 | 28 | org.springframework.cloud 29 | spring-cloud-starter-netflix-hystrix-dashboard 30 | 31 | 32 | org.springframework.cloud 33 | spring-cloud-starter-netflix-turbine 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /springcloud101-zuul-server/src/main/java/me/josephzhu/springcloud101/zuul/server/TokenFilter.java: -------------------------------------------------------------------------------- 1 | package me.josephzhu.springcloud101.zuul.server; 2 | 3 | import com.netflix.zuul.ZuulFilter; 4 | import com.netflix.zuul.context.RequestContext; 5 | import com.netflix.zuul.exception.ZuulException; 6 | import org.springframework.stereotype.Component; 7 | 8 | import javax.servlet.http.HttpServletRequest; 9 | 10 | import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_DECORATION_FILTER_ORDER; 11 | import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE; 12 | 13 | @Component 14 | public class TokenFilter extends ZuulFilter { 15 | @Override 16 | public String filterType() { 17 | return PRE_TYPE; 18 | } 19 | 20 | @Override 21 | public int filterOrder() { 22 | return PRE_DECORATION_FILTER_ORDER - 1; 23 | } 24 | 25 | @Override 26 | public boolean shouldFilter() { 27 | return true; 28 | } 29 | 30 | @Override 31 | public Object run() throws ZuulException { 32 | RequestContext ctx = RequestContext.getCurrentContext(); 33 | HttpServletRequest request = ctx.getRequest(); 34 | String token = request.getParameter("token"); 35 | if(token == null) { 36 | ctx.setSendZuulResponse(false); 37 | ctx.setResponseStatusCode(401); 38 | try { 39 | ctx.getResponse().setCharacterEncoding("UTF-8"); 40 | ctx.getResponse().getWriter().write("禁止访问"); 41 | } catch (Exception e){} 42 | 43 | return null; 44 | } 45 | return null; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /springcloud101-investservice-server/src/main/java/me/josephzhu/springcloud101/investservice/server/InvestServiceApplication.java: -------------------------------------------------------------------------------- 1 | package me.josephzhu.springcloud101.investservice.server; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.boot.CommandLineRunner; 5 | import org.springframework.boot.SpringApplication; 6 | import org.springframework.boot.autoconfigure.SpringBootApplication; 7 | import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; 8 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 9 | import org.springframework.cloud.netflix.hystrix.EnableHystrix; 10 | import org.springframework.cloud.openfeign.EnableFeignClients; 11 | import org.springframework.context.ApplicationContext; 12 | import org.springframework.data.jpa.repository.config.EnableJpaAuditing; 13 | 14 | import java.util.Arrays; 15 | import java.util.stream.Stream; 16 | 17 | @SpringBootApplication 18 | @EnableDiscoveryClient 19 | @EnableFeignClients 20 | @EnableJpaAuditing 21 | @EnableHystrix 22 | @EnableCircuitBreaker 23 | public class InvestServiceApplication implements CommandLineRunner{ 24 | public static void main(String[] args) { 25 | SpringApplication.run( InvestServiceApplication.class, args ); 26 | } 27 | 28 | @Autowired 29 | ApplicationContext applicationContext; 30 | 31 | @Override 32 | public void run(String... args) throws Exception { 33 | System.out.println("所有注解:"); 34 | Stream.of(applicationContext.getBeanDefinitionNames()) 35 | .map(applicationContext::getBean) 36 | .map(bean-> Arrays.asList(bean.getClass().getAnnotations())) 37 | .flatMap(a->a.stream()) 38 | .filter(annotation -> annotation.annotationType().getName().startsWith("org.springframework.cloud")) 39 | .forEach(System.out::println); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /springcloud101-projectservice-listener/src/main/java/me.josephzhu.springcloud101.projectservice.listener/ProjectServiceListener.java: -------------------------------------------------------------------------------- 1 | package me.josephzhu.springcloud101.projectservice.listener; 2 | 3 | import com.fasterxml.jackson.core.JsonProcessingException; 4 | import com.fasterxml.jackson.databind.ObjectMapper; 5 | import lombok.extern.slf4j.Slf4j; 6 | import me.josephzhu.springcloud101.projectservice.api.Project; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.cloud.stream.annotation.EnableBinding; 9 | import org.springframework.cloud.stream.annotation.StreamListener; 10 | import org.springframework.cloud.stream.messaging.Sink; 11 | import org.springframework.stereotype.Component; 12 | 13 | @Component 14 | @EnableBinding(Sink.class) 15 | @Slf4j 16 | public class ProjectServiceListener { 17 | @Autowired 18 | RemoteUserService remoteUserService; 19 | @Autowired 20 | RemoteProjectService remoteProjectService; 21 | @Autowired 22 | RemoteInvestService remoteInvestService; 23 | 24 | static ObjectMapper objectMapper = new ObjectMapper(); 25 | 26 | @StreamListener(Sink.INPUT) 27 | public void handleProject(Project project) { 28 | try { 29 | log.info("收到消息: " + project); 30 | if (project.getStatus() == 2) { 31 | remoteInvestService.getOrders(project.getId()) 32 | .forEach(invest -> { 33 | try { 34 | remoteUserService.lendpayMoney(invest.getInvestorId(), invest.getBorrowerId(), invest.getAmount()); 35 | } catch (Exception ex) { 36 | try { 37 | log.error("处理放款的时候遇到异常:" + objectMapper.writeValueAsString(invest), ex); 38 | } catch (JsonProcessingException e) { 39 | 40 | } 41 | } 42 | }); 43 | remoteProjectService.lendpay(project.getId()); 44 | } 45 | } catch (Exception ex) { 46 | log.error("处理消息出现异常",ex); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /springcloud101-userservice-server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | springcloud101 7 | me.josephzhu 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | springcloud101-userservice-server 13 | 14 | 15 | 16 | org.springframework.cloud 17 | spring-cloud-starter-netflix-eureka-client 18 | 19 | 20 | org.springframework.boot 21 | spring-boot-starter-web 22 | 23 | 24 | org.springframework.cloud 25 | spring-cloud-starter-openfeign 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-actuator 30 | 31 | 32 | org.springframework.cloud 33 | spring-cloud-starter-sleuth 34 | 35 | 36 | org.springframework.cloud 37 | spring-cloud-starter-zipkin 38 | 39 | 40 | org.springframework.boot 41 | spring-boot-starter-data-jpa 42 | 43 | 44 | mysql 45 | mysql-connector-java 46 | 47 | 48 | com.github.gavlyukovskiy 49 | p6spy-spring-boot-starter 50 | 1.4.3 51 | 52 | 53 | org.springframework.cloud 54 | spring-cloud-starter-netflix-hystrix 55 | 56 | 57 | org.redisson 58 | redisson-spring-boot-starter 59 | 3.8.2 60 | 61 | 62 | 63 | me.josephzhu 64 | springcloud101-userservice-api 65 | 1.0-SNAPSHOT 66 | 67 | 68 | -------------------------------------------------------------------------------- /springcloud101-investservice-server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | springcloud101 7 | me.josephzhu 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | springcloud101-investservice-server 13 | 14 | 15 | 16 | org.springframework.cloud 17 | spring-cloud-starter-netflix-eureka-client 18 | 19 | 20 | org.springframework.boot 21 | spring-boot-starter-web 22 | 23 | 24 | org.springframework.cloud 25 | spring-cloud-starter-openfeign 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-data-jpa 30 | 31 | 32 | mysql 33 | mysql-connector-java 34 | 35 | 36 | org.springframework.boot 37 | spring-boot-starter-actuator 38 | 39 | 40 | org.springframework.cloud 41 | spring-cloud-starter-sleuth 42 | 43 | 44 | org.springframework.cloud 45 | spring-cloud-starter-zipkin 46 | 47 | 48 | com.github.gavlyukovskiy 49 | p6spy-spring-boot-starter 50 | 1.4.3 51 | 52 | 53 | org.springframework.cloud 54 | spring-cloud-starter-netflix-hystrix 55 | 56 | 57 | 58 | me.josephzhu 59 | springcloud101-investservice-api 60 | 1.0-SNAPSHOT 61 | 62 | 63 | me.josephzhu 64 | springcloud101-userservice-api 65 | 1.0-SNAPSHOT 66 | 67 | 68 | me.josephzhu 69 | springcloud101-projectservice-api 70 | 1.0-SNAPSHOT 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /springcloud101-projectservice-listener/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | springcloud101 7 | me.josephzhu 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | springcloud101-projectservice-listener 13 | 14 | 15 | 16 | org.springframework.cloud 17 | spring-cloud-starter-netflix-eureka-client 18 | 19 | 20 | org.springframework.boot 21 | spring-boot-starter-web 22 | 23 | 24 | org.springframework.cloud 25 | spring-cloud-starter-openfeign 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-actuator 30 | 31 | 32 | org.springframework.cloud 33 | spring-cloud-starter-sleuth 34 | 35 | 36 | org.springframework.cloud 37 | spring-cloud-starter-zipkin 38 | 39 | 40 | org.springframework.cloud 41 | spring-cloud-starter-netflix-hystrix 42 | 43 | 44 | org.springframework.cloud 45 | spring-cloud-stream 46 | 47 | 48 | org.springframework.cloud 49 | spring-cloud-starter-stream-rabbit 50 | 51 | 52 | com.fasterxml.jackson.core 53 | jackson-databind 54 | 2.9.7 55 | 56 | 57 | 58 | me.josephzhu 59 | springcloud101-userservice-api 60 | 1.0-SNAPSHOT 61 | 62 | 63 | me.josephzhu 64 | springcloud101-projectservice-api 65 | 1.0-SNAPSHOT 66 | 67 | 68 | me.josephzhu 69 | springcloud101-investservice-api 70 | 1.0-SNAPSHOT 71 | 72 | 73 | -------------------------------------------------------------------------------- /springcloud101-userservice-server/src/main/java/me/josephzhu/springcloud101/userservice/server/UserServiceController.java: -------------------------------------------------------------------------------- 1 | package me.josephzhu.springcloud101.userservice.server; 2 | 3 | import me.josephzhu.springcloud101.userservice.api.User; 4 | import me.josephzhu.springcloud101.userservice.api.UserService; 5 | import org.redisson.api.RLock; 6 | import org.redisson.api.RedissonClient; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.transaction.annotation.Transactional; 9 | import org.springframework.web.bind.annotation.RestController; 10 | 11 | import java.math.BigDecimal; 12 | 13 | @RestController 14 | public class UserServiceController implements UserService { 15 | 16 | @Autowired 17 | UserRepository userRepository; 18 | @Autowired 19 | RedissonClient redissonClient; 20 | 21 | @Override 22 | public User getUser(long id) { 23 | return userRepository.findById(id).map(userEntity -> 24 | User.builder() 25 | .id(userEntity.getId()) 26 | .availableBalance(userEntity.getAvailableBalance()) 27 | .frozenBalance(userEntity.getFrozenBalance()) 28 | .name(userEntity.getName()) 29 | .createdAt(userEntity.getCreatedAt()) 30 | .build()) 31 | .orElse(null); 32 | } 33 | 34 | @Override 35 | public BigDecimal consumeMoney(long investorId, BigDecimal amount) { 36 | RLock lock = redissonClient.getLock("User" + investorId); 37 | lock.lock(); 38 | try { 39 | UserEntity user = userRepository.findById(investorId).orElse(null); 40 | if (user != null && user.getAvailableBalance().compareTo(amount)>=0) { 41 | user.setAvailableBalance(user.getAvailableBalance().subtract(amount)); 42 | user.setFrozenBalance(user.getFrozenBalance().add(amount)); 43 | userRepository.save(user); 44 | return amount; 45 | } 46 | return null; 47 | } finally { 48 | lock.unlock(); 49 | } 50 | } 51 | 52 | @Override 53 | @Transactional(rollbackFor = Exception.class) 54 | public BigDecimal lendpayMoney(long investorId, long borrowerId, BigDecimal amount) throws Exception { 55 | RLock lock = redissonClient.getLock("User" + investorId); 56 | lock.lock(); 57 | try { 58 | UserEntity investor = userRepository.findById(investorId).orElse(null); 59 | UserEntity borrower = userRepository.findById(borrowerId).orElse(null); 60 | 61 | if (investor != null && borrower != null && investor.getFrozenBalance().compareTo(amount) >= 0) { 62 | investor.setFrozenBalance(investor.getFrozenBalance().subtract(amount)); 63 | userRepository.save(investor); 64 | borrower.setAvailableBalance(borrower.getAvailableBalance().add(amount)); 65 | userRepository.save(borrower); 66 | return amount; 67 | } 68 | return null; 69 | } finally { 70 | lock.unlock(); 71 | } 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /springcloud101-projectservice-server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | springcloud101 7 | me.josephzhu 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | springcloud101-projectservice-server 13 | 14 | 15 | 16 | org.springframework.cloud 17 | spring-cloud-starter-netflix-eureka-client 18 | 19 | 20 | org.springframework.boot 21 | spring-boot-starter-web 22 | 23 | 24 | org.springframework.cloud 25 | spring-cloud-starter-openfeign 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-data-jpa 30 | 31 | 32 | mysql 33 | mysql-connector-java 34 | 35 | 36 | org.springframework.boot 37 | spring-boot-starter-actuator 38 | 39 | 40 | org.springframework.cloud 41 | spring-cloud-starter-sleuth 42 | 43 | 44 | org.springframework.cloud 45 | spring-cloud-starter-zipkin 46 | 47 | 48 | com.github.gavlyukovskiy 49 | p6spy-spring-boot-starter 50 | 1.4.3 51 | 52 | 53 | org.springframework.cloud 54 | spring-cloud-starter-netflix-hystrix 55 | 56 | 57 | org.springframework.cloud 58 | spring-cloud-stream 59 | 60 | 61 | org.springframework.cloud 62 | spring-cloud-starter-stream-rabbit 63 | 64 | 65 | 66 | me.josephzhu 67 | springcloud101-projectservice-api 68 | 1.0-SNAPSHOT 69 | 70 | 71 | me.josephzhu 72 | springcloud101-userservice-api 73 | 1.0-SNAPSHOT 74 | 75 | 76 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | me.josephzhu 8 | springcloud101 9 | pom 10 | 1.0-SNAPSHOT 11 | 12 | springcloud101-investservice-api 13 | springcloud101-investservice-server 14 | springcloud101-userservice-api 15 | springcloud101-userservice-server 16 | springcloud101-projectservice-api 17 | springcloud101-projectservice-server 18 | springcloud101-eureka-server 19 | springcloud101-zuul-server 20 | springcloud101-turbine-server 21 | springcloud101-projectservice-listener 22 | springcloud101-admin-server 23 | 24 | 25 | 26 | org.springframework.boot 27 | spring-boot-starter-parent 28 | 2.0.5.RELEASE 29 | 30 | 31 | 32 | 33 | UTF-8 34 | UTF-8 35 | 1.8 36 | 37 | 38 | 39 | 40 | org.projectlombok 41 | lombok 42 | true 43 | 44 | 45 | 46 | 47 | 48 | 49 | org.springframework.cloud 50 | spring-cloud-dependencies 51 | Finchley.RELEASE 52 | pom 53 | import 54 | 55 | 56 | org.springframework.data 57 | spring-data-releasetrain 58 | Lovelace-RELEASE 59 | import 60 | pom 61 | 62 | 63 | org.springframework.cloud 64 | spring-cloud-stream-dependencies 65 | Fishtown.M3 66 | pom 67 | import 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | org.springframework.boot 77 | spring-boot-maven-plugin 78 | 79 | 80 | 81 | 82 | 83 | 84 | spring-milestones 85 | Spring Milestones 86 | https://repo.spring.io/libs-milestone 87 | 88 | false 89 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /springcloud101-investservice-server/src/main/java/me/josephzhu/springcloud101/investservice/server/InvestServiceController.java: -------------------------------------------------------------------------------- 1 | package me.josephzhu.springcloud101.investservice.server; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import me.josephzhu.springcloud101.investservice.api.Invest; 5 | import me.josephzhu.springcloud101.investservice.api.InvestService; 6 | import me.josephzhu.springcloud101.projectservice.api.Project; 7 | import me.josephzhu.springcloud101.userservice.api.User; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.transaction.annotation.Transactional; 10 | import org.springframework.web.bind.annotation.RestController; 11 | 12 | import java.math.BigDecimal; 13 | import java.util.List; 14 | import java.util.stream.Collectors; 15 | 16 | @RestController 17 | @Slf4j 18 | public class InvestServiceController implements InvestService { 19 | @Autowired 20 | InvestRepository investRepository; 21 | @Autowired 22 | RemoteUserService remoteUserService; 23 | @Autowired 24 | RemoteProjectService remoteProjectService; 25 | 26 | @Override 27 | @Transactional(rollbackFor = Exception.class) 28 | public Invest createOrder(long userId, long projectId, BigDecimal amount) throws Exception { 29 | User investor = remoteUserService.getUser(userId); 30 | if (investor == null) throw new Exception("无效用户ID"); 31 | if (amount.compareTo(investor.getAvailableBalance()) > 0) throw new Exception("用户余额不足"); 32 | 33 | Project project = remoteProjectService.getProject(projectId); 34 | if (project == null) throw new Exception("无效项目ID"); 35 | if (amount.compareTo(project.getRemainAmount()) > 0) throw new Exception("项目余额不足"); 36 | if (project.getStatus() !=1) throw new Exception("项目不是募集中状不能投资"); 37 | 38 | InvestEntity investEntity = new InvestEntity(); 39 | investEntity.setInvestorId(investor.getId()); 40 | investEntity.setInvestorName(investor.getName()); 41 | investEntity.setAmount(amount); 42 | investEntity.setBorrowerId(project.getBorrowerId()); 43 | investEntity.setBorrowerName(project.getBorrowerName()); 44 | investEntity.setProjectId(project.getId()); 45 | investEntity.setProjectName(project.getName()); 46 | investEntity.setStatus(1); 47 | investRepository.save(investEntity); 48 | 49 | if (remoteUserService.consumeMoney(userId, amount) == null) throw new Exception("用户消费失败"); 50 | if (remoteProjectService.gotInvested(projectId, amount) == null) throw new Exception("项目投资失败"); 51 | 52 | return Invest.builder() 53 | .id(investEntity.getId()) 54 | .amount(investEntity.getAmount()) 55 | .borrowerId(investEntity.getBorrowerId()) 56 | .investorId(investEntity.getInvestorId()) 57 | .projectId(investEntity.getProjectId()) 58 | .status(investEntity.getStatus()) 59 | .createdAt(investEntity.getCreatedAt()) 60 | .updatedAt(investEntity.getUpdatedAt()) 61 | .build(); 62 | } 63 | 64 | @Override 65 | public List getOrders(long projectId) throws Exception { 66 | return investRepository.findByProjectIdAndStatus(projectId,1).stream() 67 | .map(investEntity -> Invest.builder() 68 | .id(investEntity.getId()) 69 | .amount(investEntity.getAmount()) 70 | .borrowerId(investEntity.getBorrowerId()) 71 | .investorId(investEntity.getInvestorId()) 72 | .projectId(investEntity.getProjectId()) 73 | .status(investEntity.getStatus()) 74 | .createdAt(investEntity.getCreatedAt()) 75 | .updatedAt(investEntity.getUpdatedAt()) 76 | .build()) 77 | .collect(Collectors.toList()); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /springcloud101-projectservice-server/src/main/java/me/josephzhu/springcloud101/projectservice/server/ProjectServiceController.java: -------------------------------------------------------------------------------- 1 | package me.josephzhu.springcloud101.projectservice.server; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import me.josephzhu.springcloud101.projectservice.api.Project; 5 | import me.josephzhu.springcloud101.projectservice.api.ProjectService; 6 | import me.josephzhu.springcloud101.userservice.api.User; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.cloud.stream.annotation.EnableBinding; 9 | import org.springframework.cloud.stream.messaging.Source; 10 | import org.springframework.integration.support.MessageBuilder; 11 | import org.springframework.web.bind.annotation.RestController; 12 | 13 | import java.math.BigDecimal; 14 | 15 | @RestController 16 | @Slf4j 17 | @EnableBinding(Source.class) 18 | public class ProjectServiceController implements ProjectService { 19 | 20 | @Autowired 21 | ProjectRepository projectRepository; 22 | @Autowired 23 | RemoteUserService remoteUserService; 24 | 25 | @Override 26 | public Project getProject(long id) throws Exception { 27 | ProjectEntity projectEntity = projectRepository.findById(id).orElse(null); 28 | if (projectEntity == null) return null; 29 | User borrower = remoteUserService.getUser(projectEntity.getBorrowerId()); 30 | if (borrower == null) return null; 31 | 32 | return Project.builder() 33 | .id(projectEntity.getId()) 34 | .borrowerId(borrower.getId()) 35 | .borrowerName(borrower.getName()) 36 | .name(projectEntity.getName()) 37 | .reason(projectEntity.getReason()) 38 | .status(projectEntity.getStatus()) 39 | .totalAmount(projectEntity.getTotalAmount()) 40 | .remainAmount(projectEntity.getRemainAmount()) 41 | .createdAt(projectEntity.getCreatedAt()) 42 | .build(); 43 | } 44 | 45 | @Override 46 | public BigDecimal gotInvested(long id, BigDecimal amount) throws Exception { 47 | ProjectEntity projectEntity = projectRepository.findById(id).orElse(null); 48 | if (projectEntity != null && projectEntity.getRemainAmount().compareTo(amount)>=0) { 49 | projectEntity.setRemainAmount(projectEntity.getRemainAmount().subtract(amount)); 50 | projectRepository.save(projectEntity); 51 | 52 | if (projectEntity.getRemainAmount().compareTo(new BigDecimal("0"))==0) { 53 | User borrower = remoteUserService.getUser(projectEntity.getBorrowerId()); 54 | if (borrower != null) { 55 | projectEntity.setStatus(2); 56 | projectRepository.save(projectEntity); 57 | projectStatusChanged(Project.builder() 58 | .id(projectEntity.getId()) 59 | .borrowerId(borrower.getId()) 60 | .borrowerName(borrower.getName()) 61 | .name(projectEntity.getName()) 62 | .reason(projectEntity.getReason()) 63 | .status(projectEntity.getStatus()) 64 | .totalAmount(projectEntity.getTotalAmount()) 65 | .remainAmount(projectEntity.getRemainAmount()) 66 | .createdAt(projectEntity.getCreatedAt()) 67 | .build()); 68 | } 69 | return amount; 70 | } 71 | return amount; 72 | } 73 | return null; 74 | } 75 | 76 | @Override 77 | public BigDecimal lendpay(long id) throws Exception { 78 | Thread.sleep(5000); 79 | ProjectEntity project = projectRepository.findById(id).orElse(null); 80 | if (project != null) { 81 | project.setStatus(3); 82 | projectRepository.save(project); 83 | return project.getTotalAmount(); 84 | } 85 | return null; 86 | } 87 | 88 | @Autowired 89 | Source source; 90 | 91 | private void projectStatusChanged(Project project){ 92 | if (project.getStatus() == 2) 93 | try { 94 | source.output().send(MessageBuilder.withPayload(project).build()); 95 | } catch (Exception ex) { 96 | log.error("发送MQ失败", ex); 97 | } 98 | } 99 | } 100 | --------------------------------------------------------------------------------