目录
构建SpringCloud项目
创建服务注册中心(Eureka Server)
在IDEA中,new project - Spring Initializr,next,选择Cloud Discovery,右边勾选Eureka Server,next
- 配置文件如下
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.qyluo</groupId> <artifactId>springcloud-demo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>springcloud-demo</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.6.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <spring-cloud.version>Dalston.SR3</spring-cloud.version> </properties> <dependencies> <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-eureka-server --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> <version>1.4.4.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
- application.properties
server.port=8761 eureka.instance.hostname=localhost eureka.client.register-with-eureka=false eureka.client.fetch-registry=false eureka.client.service-url.defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
- SpringcloudDemoApplication类
package com.qyluo.springclouddemo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @EnableEurekaServer @SpringBootApplication public class SpringcloudDemoApplication { public static void main(String[] args) { SpringApplication.run(SpringcloudDemoApplication.class, args); } }
创建服务提供者
创建项目过程类似上边的服务注册中心创建,只是需要更改一些配置文件
- pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.qyluo</groupId> <artifactId>springcloud-server</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>springcloud-server</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.6.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <spring-cloud.version>Dalston.SR3</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</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-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
- application.properties
server.port=8762 spring.application.name=springcloud-server eureka.client.service-url.defaultZone: http://localhost:8761/eureka/
- SpringcloudServerApplication类
package com.qyluo.springcloudserver; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.netflix.feign.EnableFeignClients; import org.springframework.context.annotation.ComponentScan; @ComponentScan("com.qyluo.springcloudserver") @EnableDiscoveryClient @EnableFeignClients @SpringBootApplication public class SpringcloudServerApplication { public static void main(String[] args) { SpringApplication.run(SpringcloudServerApplication.class, args); } }
- 添加一个TestController类
package com.qyluo.springcloudserver.controller; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * @author qiyao.luo * @create 2018/6/11 */ @RestController public class TestController { @Value("${server.port}") String port; @RequestMapping("/test") public String test() { return "server被调用了:" + port; } }
创建服务提供者2
- 如上再添加一个创建服务提供者,spring.application.name相同,server.port不同,可以实现负载均衡
创建服务消费者(基于Feign)
除了Feign方式,还有rest+ribbon的方式
- 项目创建过程如上
- pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.qyluo</groupId> <artifactId>springcloud-customer</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>springcloud-customer</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.6.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <spring-cloud.version>Dalston.SR3</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</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-eureka-server</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
- application.properties
eureka.client.service-url.defaultZone: http://localhost:8761/eureka/ server.port=8764 spring.application.name=springcloud-customer
- SpringcloudCustomerApplication类
package com.qyluo.springcloudcustomer; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.netflix.feign.EnableFeignClients; @EnableFeignClients @EnableDiscoveryClient @SpringBootApplication public class SpringcloudCustomerApplication { public static void main(String[] args) { SpringApplication.run(SpringcloudCustomerApplication.class, args); } }
- TestController类
package com.qyluo.springcloudcustomer.controller; import com.qyluo.springcloudcustomer.service.TestService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; /** * @author qiyao.luo * @create 2018/6/12 */ @RestController public class TestController { @Autowired TestService testService; @RequestMapping(value = "/test", method = RequestMethod.GET) public String test() { return testService.test(); } }
- TestService类
package com.qyluo.springcloudcustomer.service; import org.springframework.cloud.netflix.feign.FeignClient; import org.springframework.web.bind.annotation.RequestMapping; /** * @author qiyao.luo * @create 2018/6/12 */ @FeignClient(value = "springcloud-server") public interface TestService { @RequestMapping("/test") String test(); }
相关说明
- pom.xml引入包的选择问题
使用最新的 spring-cloud-starter-netflix-eureka-server,而spring-cloud-starter-eureka-server已经过期。 - @EnableEurekaClient和@EnableDiscoveryClient的区别
spring cloud中discovery service有许多种实现(eureka、consul、zookeeper等等),@EnableDiscoveryClient基于spring-cloud-commons,@EnableEurekaClient基于spring-cloud-netflix。
就是如果选用的注册中心是eureka,那么就推荐@EnableEurekaClient,如果是其他的注册中心,那么推荐使用@EnableDiscoveryClient。
启动项目
- 所有项目都启动后,可通过http://localhost:8761/访问Eureka服务注册中心,访问http://localhost:8764/test调用服务
建立分布式配置中心组件config server
- 建立一个spring-boot项目,pom.xml为
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.qyluo</groupId> <artifactId>springcloud-configserver</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>springcloud-configserver</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.6.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <spring-cloud.version>Dalston.SR3</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-server</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
- 入口类
package com.qyluo.springcloudconfigserver; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.config.server.EnableConfigServer; @EnableConfigServer @SpringBootApplication public class SpringcloudConfigserverApplication { public static void main(String[] args) { SpringApplication.run(SpringcloudConfigserverApplication.class, args); } }
- application.properties
spring.application.name=config-server server.port=8888 #设置配置文件在本地 spring.profiles.active=native #设置配置文件的目录 spring.cloud.config.server.native.search-locations=D:/testconfig #设置git仓库地址,公共仓库不需要用户名密码 #spring.cloud.config.server.git.uri=https://github.com/forezp/SpringcloudConfig/ #spring.cloud.config.server.git.searchPaths=respo #spring.cloud.config.label=master #spring.cloud.config.server.git.username=your username #spring.cloud.config.server.git.password=your password
- http请求地址和资源文件映射如下:
/{application}/{profile}[/{label}] /{application}-{profile}.yml /{label}/{application}-{profile}.yml /{application}-{profile}.properties /{label}/{application}-{profile}.properties
构建一个config client
- 在spring-boot项目中,pom.xml中加入如下依赖:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency>
application.properties
eureka.client.service-url.defaultZone: http://localhost:8761/eureka/ server.port=8764 spring.application.name=config-client spring.cloud.config.label=master spring.cloud.config.profile=dev spring.cloud.config.uri= http://localhost:8888/
- 测试,在controller中加入
@Value("${foo}") String foo; @RequestMapping(value = "/testconfig") public String testconfig() { return foo; }
构建高可用分布式配置中心组件config server
- 将config server注册到服务注册中心
- config client配置:
application.properties
eureka.client.service-url.defaultZone: http://localhost:8761/eureka/ server.port=8764 spring.application.name=config-client spring.cloud.config.label=master spring.cloud.config.profile=dev spring.cloud.config.uri= http://localhost:8888/ spring.cloud.config.discovery.enabled=true spring.cloud.config.discovery.serviceId=config-server
读取配置文件不再写ip地址,而是服务名,这时如果配置服务部署多份,通过负载均衡,从而高可用
使用断路器Hystrix
在ribbon使用断路器
添加依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency>
在程序的启动类加@EnableHystrix注解开启Hystrix:
@EnableFeignClients @EnableDiscoveryClient @EnableHystrix @SpringBootApplication public class SpringcloudCustomerApplication { public static void main(String[] args) { SpringApplication.run(SpringcloudCustomerApplication.class, args); } @Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); } }
改造service类,加上@HystrixCommand注解。该注解对该方法创建了熔断器的功能,并指定了fallbackMethod熔断方法,熔断方法直接返回了一个字符串
@Service public class TestService2 { @Autowired RestTemplate restTemplate; @HystrixCommand(fallbackMethod = "hiError") public String hiService() { return restTemplate.getForObject("http://springcloud-server/test", String.class); } public String hiError() { return "hi, sorry, error"; } }
在Feign中使用断路器
在配置文件中加入:
feign.hystrix.enabled=true
在FeignClient的TestService接口的注解加入fallback的指定类,该指定类实现TestService接口,并注入IOC容器中
@FeignClient(value = "springcloud-server", fallback = TestServiceHystrix.class) public interface TestService { @RequestMapping("/test") String test(); } @Component public class TestServiceHystrix implements TestService { @Override public String test() { return "hi, sorry, hystrix"; } }
使用Hystrix Dashboard(断路器:Hystrix 仪表盘)
加入依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId> </dependency>
主程序启动类加入@EnableHystrixDashboard注解
@EnableFeignClients @EnableDiscoveryClient @EnableHystrix @EnableHystrixDashboard @SpringBootApplication public class SpringcloudCustomerApplication { public static void main(String[] args) { SpringApplication.run(SpringcloudCustomerApplication.class, args); } @Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); } }
打开浏览器:访问http://localhost:8764/hystrix
路由网关(zuul)
Zuul的主要功能是路由转发和过滤器。路由功能是微服务的一部分,比如/api/user转发到到user服务,/api/shop转发到到shop服务。zuul默认和Ribbon结合实现了负载均衡的功能。
创建新工程,依赖为:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.qyluo</groupId> <artifactId>springcloud-zuul</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>springcloud-zuul</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.6.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <spring-cloud.version>Dalston.SR3</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zuul</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-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
在入口类加入注解@EnableZuulProxy,开启zuul的功能
@SpringBootApplication @EnableEurekaClient @EnableDiscoveryClient @EnableZuulProxy public class SpringcloudZuulApplication { public static void main(String[] args) { SpringApplication.run(SpringcloudZuulApplication.class, args); } }
配置文件如下:
server.port=8766 spring.application.name=springcloud-zuul eureka.client.service-url.defaultZone: http://localhost:8761/eureka/ zuul.routes.api-server.path=/api-server/** zuul.routes.api-server.service-id=springcloud-server zuul.routes.api-customer.path=/api-customer/** zuul.routes.api-customer.service-id=springcloud-customer
首先指定服务注册中心的地址为http://localhost:8761/eureka/,服务的端口为8766,服务名为springcloud-zuul;以/api-server/ 开头的请求都转发给springcloud-server服务;以/api-customer/开头的请求都转发给springcloud-customer服务;
服务过滤
zuul不仅只是路由,并且还能过滤,做一些安全验证。
增加继承ZuulFilter的MyFilter类
public class MyFilter extends ZuulFilter { @Override public String filterType() { return "pre"; } @Override public int filterOrder() { return 0; } @Override public boolean shouldFilter() { return true; } @Override public Object run() { RequestContext ctx = RequestContext.getCurrentContext(); HttpServletRequest request = ctx.getRequest(); Object token = request.getParameter("token"); if (token == null) { ctx.setSendZuulResponse(false); ctx.setResponseStatusCode(401); try { ctx.getResponse().getWriter().write("token is empty"); } catch (IOException e) { } return null; } return null; } }
需要将MyFilter注入IOC容器,可通过如下方式:
@SpringBootApplication @EnableEurekaClient @EnableDiscoveryClient @EnableZuulProxy public class SpringcloudZuulApplication { public static void main(String[] args) { SpringApplication.run(SpringcloudZuulApplication.class, args); } @Bean MyFilter myFilter() { return new MyFilter(); } }
消息总线
Spring Cloud Bus 将分布式的节点用轻量的消息代理连接起来。它可以用于广播配置文件的更改或者服务之间的通讯,也可以用于监控。
下载安装RabbitMQ
改造config-client
添加依赖
<dependencies> <dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</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-aop</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </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> </dependencies>
application.properties添加RabbitMQ的配置
spring.rabbitmq.host=localhost spring.rabbitmq.port=5672 # spring.rabbitmq.username= # spring.rabbitmq.password=
只需要发送post请求:http://localhost:8881/bus/refresh,config-client会重新读取配置文件
来源:https://www.cnblogs.com/kioluo/p/9516666.html