基于springcloud的微服务架构搭建项目见github项目:microservice-sc=v1.0 ,后续会不断更新搭建过程并添加底层业务组件,若是您喜欢的话给颗star小星星吧,您的确定是我创做的动力!前端
this is a microservice platform based on spring cloudgit
这是一个基于 springcloud 的分布式微服务架构,版本 v1.0是无业务组件逻辑的架构。在后续会不断优化框架使其知足一些底层业务需求。github
以下 module 项目按照序号依次排序讲解,parent 为父模块,主要是作了 spring-boot 和 spring-cloud 依赖引入和版本管理,spring-boot 版本为2.0.3.RELEASE,spring-cloud 版本为 Finchley.RELEASE.web
parent ├─.settings ├─module-config-client ##6.配置读取客户端,可在1.服务注册中心注册,该服务中的配置信息能够读取5.配置服务中心中的配置信息,并可以经过消息总线bus来保证读取的配置信息为最新 │ ├─module-config-server ##5.配置服务中心,可在1.服务注册中心注册,能够访问本地或者远程git仓库的配置文件信息 │ ├─module-eureka-server ##1.eureka服务注册中心 │ ├─module-service-feign ##3.2.须要在1.注册中心注册,并能够访问2.已注册服务的客户端(feign实现) │ ├─module-service-gateway ##4.2.路由转发服务,做用同4.1.比较主流的一种路由分发服务实现 │ ├─module-service-hi ##2.须要在1.注册中心注册的服务 │ ├─module-service-ribbon ##3.1.须要在1.注册中心注册,并能够访问2.已注册服务的客户端(ribbon实现) │ ├─module-service-zuul ##4.1.路由转发服务,负责将客户的请求根据url路径分发到不一样的服务访问客户端(3.1 or 3.2)
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency>
@SpringBootApplication @EnableEurekaServer public class EurekaServerApplication { public static void main(String[] args) { SpringApplication.run(EurekaServerApplication.class, args); } }
server: port: 8761 #服务启动后监听端口 eureka: instance: hostname: localhost #服务实例访问ip client: register-with-eureka: false #自己为服务注册中心,不须要注册 fetch-registry: false service-url: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #须要注册到该中心的服务须要访问的地址url spring: application: name: eureka-server #该注册中心的名称,该名称惟一,能够被其余服务识别
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId> </dependency>
** eureka-client - 可注册的客户端依赖 ** ** starter-web - web 服务 ** ** hystrix - 熔断器相关组件 ** ** actuator - 监控相关组件 **
@SpringBootApplication @EnableEurekaClient @EnableDiscoveryClient @RestController @EnableHystrix @EnableHystrixDashboard @EnableCircuitBreaker public class ServiceHiApplication { public static void main(String[] args) { SpringApplication.run(ServiceHiApplication.class, args); } @Value("${server.port}") String port; @RequestMapping("/hi") @HystrixCommand(fallbackMethod="hiError") public String sayHi(@RequestParam(value="name", defaultValue="fujian") String name) { return "hi, " + name + ", i am from port:" + port; } public String hiError(String name) { return "hi, " + name + ", error happens"; } }
@EnableEurekaClient - 代表这是一个可注册的客户端 @EnableDiscoveryClient - 做用同上 @EnableHystrix/@EnableCircuitBreaker - 使其具备熔断器功能 @EnableHystrixDashboard - 使其具备熔断器dashboard功能 @RestController - 这是一个cotroller
server: port: 8762 spring: application: name: service-hi eureka: client: service-url: defaultZone: http://localhost:8761/eureka/ #服务注册到该地址的服务注册中心 management: #该设置容许该服务能够被http访问,如查看服务 actuator 等信息 endpoints: web: exposure: include: "*" cors: allowed-origins: "*" allowed-methods: "*"
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency>
@Service public class HiService { @Autowired RestTemplate restTemplate; @HystrixCommand(fallbackMethod="hiError") public String sayhi(String name) { return restTemplate.getForObject("http://SERVICE-HI/hi?name="+name, String.class); } public String hiError(String name) { return "hi," + name + ",sorry,error!"; } }
@SpringBootApplication @EnableEurekaClient @EnableDiscoveryClient @EnableHystrix public class ServiceRibbonApplication { public static void main(String[] args) { SpringApplication.run(ServiceRibbonApplication.class, args); } @Bean @LoadBalanced RestTemplate restTemplate() { return new RestTemplate(); } }
首先看方法上的 @HystrixCommand 注释,该注释代表调用该方法服务不可用时交由 fallbackMethod 指向的方法处理。而后 sayhi 方法内使用 restTemplate 去访问 service-hi 服务,因为该服务已在注册中心注册,因此访问 SERVICE-HI 惟一标识即可访问到已注册的服务。restTemplate 在启动类中经过@Bean 实例化,经过 @LoadBalanced 使其具备负载均衡功能,即当经过该模块访问一个服务集群时会均衡分发请求。spring
eureka: client: service-url: defaultZone: http://localhost:8761/eureka/ server: port: 8764 spring: application: name: service-ribbon
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
@FeignClient(value="service-hi", fallback=HiServiceHystrix.class) public interface HiSerivceInterface { @GetMapping("/hi") public String sayHi(@RequestParam(value="name") String name); }
@Component public class HiServiceHystrix implements HiSerivceInterface { @Override public String sayHi(String name) { return "sorry," + name + ", it has a error"; } }
@FeignClient的 value 将 /hi 访问转递给 service-hi 服务,假如访问服务失败则请求交由 HiServiceHystrix 处理,能够看到 HiServiceHystrix 实现了 HiSerivceInterface 接口。bootstrap
eureka: client: service-url: defaultZone: http://localhost:8761/eureka/ server: port: 8765 spring: application: name: service-feign feign: hystrix: enabled: true
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</artifactId> </dependency>
@SpringBootApplication @EnableEurekaClient @EnableDiscoveryClient @EnableZuulProxy public class ServiceZuulApplication { public static void main(String[] args) { SpringApplication.run(ServiceZuulApplication.class, args); } }
@EnableZuulProxy 启动zuul功能api
eureka: client: service-url: defaultZone: http://localhost:8761/eureka/ server: port: 8769 spring: application: name: service-zuul zuul: routes: api-a: path: /api-a/** service-id: service-ribbon #请求路径/api-a/ 路由给 service-ribbon 服务 api-b: path: /api-b/** service-id: service-feign #请求路径/api-b/ 路由给 service-feign 服务
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>
server: port: 8081 spring: application: name: service-gateway cloud: gateway: discovery: locator: enabled: false lower-case-service-id: true routes: #将请求路径 /demo/** 路由至 service-hi 服务,filter 将请求 /path 前缀去掉 - id: service-hi uri: lb://SERVICE-HI predicates: - Path=/demo/** filters: - StripPrefix=1 eureka: client: service-url: defaultZone: http://localhost:8761/eureka/
该服务提供了实时读取配置信息源的服务,当配置源的配置信息修改后,该服务会实时获取最新的配置信息,从而使读取该配置服务的客户端获取最新的配置信息。本次 demo 主要读取了 git repository 中的配置信息。架构
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-server</artifactId> </dependency>
@SpringBootApplication @EnableEurekaClient @EnableConfigServer public class ConfigServerApplication { public static void main(String[] args) { SpringApplication.run(ConfigServerApplication.class, args); } }
spring: application: name: config-server cloud: config: server: git: uri: https://github.com/linfujian/springCloudConfig #git 仓库的 uri search-paths: - config #搜索路径 label: master #指定哪个分支 server: port: 8888 eureka: client: service-url: defaultZone: http://localhost:8761/eureka/
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
@SpringBootApplication @RestController @EnableEurekaClient @EnableDiscoveryClient @RefreshScope public class ConfigClientApplication { public static void main(String[] args) { SpringApplication.run(ConfigClientApplication.class, args); } @Value("${foo}") String foo; @GetMapping("/hi") public String readConfigValue() { return foo; } }
@RefreshScope 对每次方法的调用都会刷新实例,也就是会读取到最新的属性 foo ,能够看下注解注释。app
spring.application.name=config-client spring.cloud.config.label=master spring.cloud.config.profile=dev server.port=8882 eureka.client.service-url.defaultZone=http://localhost:8761/eureka/ spring.cloud.config.discovery.enabled=true #能够发现 配置服务 功能开启 spring.cloud.config.discovery.serviceId=config-server #指向配置服务的 name
##rabbitmq 链接 相关配置,做为消息总线 spring.rabbitmq.host=localhost spring.rabbitmq.port=5672 spring.rabbitmq.username=guest spring.rabbitmq.password=guest spring.cloud.bus.enabled=true spring.cloud.bus.trace.enabled=true management.endpoints.web.exposure.include=bus-refresh #该服务能够接受外部 bus-refresh web 请求,来更新客户端读取的配置信息
1.web 前端发送 bus-refresh 请求,该请求达到8882实例后,请求 config-server 读取 git repo 得到最新配置信息 2.bus-refresh 请求同时也会发给消息总线,订阅了该总线的8881和8883实例接收到配置更新请求,也去请求 config-server 读取 git repo 得到最新配置信息