新建一个项目microservice
,maven项目,这个项目是父项目,所以只建一个java project
即可。
在name
标签上边加上配置,声明该项目为springboot
项目
<modules>
<module>provider-usermodule>
<module>consumer-ordermodule>
modules>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>1.5.3.RELEASEversion>
parent>
<name>microserviceTwoname>
<url>http://www.example.comurl>
加上下面的依赖,否则可能会报错。
<dependency>
<groupId>ch.qos.logbackgroupId>
<artifactId>logback-coreartifactId>
<version>1.2.3version>
dependency>
<dependency>
<groupId>ch.qos.logbackgroupId>
<artifactId>logback-classicartifactId>
<version>1.2.3version>
dependency>
然后在父项目上新建两个Module
,分别是提供者provider-user
和消费者consumer-order
提供者配置pom
文件,加上一下配置标志为springboot
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
然后新建application.yml
配置文件
server:
port: 7900 #程序启动后的端口
spring:
application:
name: provider-user #应用名称,别名
写一个User实体类,加上构造器,接下来要传值
package com.qianlong.User;
import java.util.Date;
public class User {
private Long id;
private Date date;
public User(){
super();
}
public User(Long id) {
this.id = id;
this.date=new Date();
}
}
写一个controller,去拿User的信息
@RestController
public class UserController {
@GetMapping("/user/{id}")
public User getUser(@PathVariable Long id){
return new User(id);
}
}
启动项目的启动类ProviderUser
很明显,在浏览器输入地址:localhost:7900/user/1可以得到一个user的信息
然后再新建一个Module
和提供者模块一样,加上依赖标志为springboot项目
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
同样,这个模块也写一个同上的user类,以及构造方法
然后写controller
@RestController
public class OrderController {
@Autowired
private RestTemplate restTemplate;//spring提供的一个用于访问rest接口的模板对象
@Value("${user.url}")//去配置文件中去取值然后赋值给url
private String url;
//private String url="http://localhost:7900/user/";
@GetMapping("/order/{id}")
public User getOrder(@PathVariable Long id){
//访问提供者,获取数据
User user = restTemplate.getForObject(url + id, User.class);//通过访问rest获取到json数据,然后转换为user对象
return user;
}
}
说明:springboot
项目的配置文件application.yml默认在resources
文件夹下,把resources
文件夹标记为资源文件后项目可自动读取到配置文件。
这样子的话,在浏览器访问localhost:8900/order/1
时,也可以得到user的信息。上面通过RestTemplate
模板对象的getForObject
方法可以访问其他Module
的路径,由消费者指向提供者。
这也体现出了springCloud
微服务的一点感觉,可以把业务模块进行拆分。但是上面的不是springcloud
项目,现在开始写springcloud
项目。
在上面的项目的基础上进行改动,首先在父项目的pom中加入springCloud
依赖标注为springCloud
项目。
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-dependenciesartifactId>
<version>Finchley.M9version>
<type>pomtype>
<scope>importscope>
dependency>
dependencies>
dependencyManagement>
父项目中的每一个Module
都是一个服务。
这里要引入Eureka
,它是一个服务注册中心,是Netflix
开发的服务发现框架,本身是一个基于REST
的服务,主要用于定位运行在AWS
域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的。SpringCloud
将它集成在其子项目spring-cloud-netflix
中,以实现SpringCloud
的服务发现功能。
需要把服务都注册到EurekaServer
中。
在父项目中新建一个Module
,起名为Eureka
,作为注册服务中心。
在pom
中加入EurekaServer
依赖
下面的安全依赖是进入eureka的url时要输入用户名和密码,启动eureka会在控制台打印出一个默认的随机密码,也可以在配置文件中进行配置用户名和密码
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-serverartifactId>
<version>1.4.3.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-securityartifactId>
dependency>
在EurekaServer
中写启动类,加上注解@EnableEurekaServer
把当前项目标记为eureka server
@SpringBootApplication
@EnableEurekaServer
public class EurekaApp
{
public static void main( String[] args )
{
SpringApplication.run(EurekaApp.class);
}
}
然后创建文件resources
并标志成资源文件,然后新建application.yml
文件,加入配置
server:
port: 10000
# 因为当前的eureka是单机的,所以需要做一些配置
eureka:
client:
register-with-eureka: false
fetch-registry: false
service-url:
# defaultZone: http://localhost:10000/eureka # 访问eureka路径
defaultZone: http://user:123@localhost:10000/eureka # 访问eureka路径
security:
basic:
enabled: true # 开启安全配置,也就是需要密码,如果不需要设置成false,注意,这个参数必须放在application.yml中,不允许放在bootstrap.yml中
user:
name: user
password: 123 # 在配置了用户名和密码之后,我们可以修改地址的访问风格为curl风格
然后通过localhost:10000
访问
在提供者provider-user
的项目中加入eureka-client
依赖,标记为客户端(EurekaServer为服务端
)
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
<version>1.4.3.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-actuatorartifactId>
dependency>
application.yml
加入eureka client
的配置,路径和EurekaServer
的路径相同。
server:
port: 7900 #程序启动后的端口
spring:
application:
name: provider-user #应用名称,别名
eureka:
client:
service-url:
defaultZone: http://user:123@localhost:10000/eureka
最后在启动类上加上注解@EnableEurekaClient
标志为eureka
的客户端。
先启动EurekaServer
模块的启动类,再启动提供者provider-user
的启动类,再浏览器url输入地址:localhost:10000
,进入到eureka
页面,会看到提供者已注册到EurekaServer
中。
在提供者provider-user
模块的controller中注入EurekaClient
,并写方法,info方法中的内容可以获取到服务的url路径。
@RestController
public class UserController {
@Autowired
private EurekaClient eurekaClient;
@GetMapping("/eurekaInfo")
public String info(){
InstanceInfo instanceInfo = eurekaClient.getNextServerFromEureka("PROVIDER-USER", false);
return instanceInfo.getHomePageUrl();
}
然后先启动eureka
服务端,再启动provider-user
客户端,输入路径localhost:10000
,点击下面服务的路径
会得到服务对应的url
和上面一样,把消费者consumer-order
模块也注册到eureka
服务中。
这样,重新刷新eureka
页面,就会看到已经有两个服务了,点击消费者服务的路径,输入消费者consumer-order
模块中的controller
方法路径到url上面,可以出查询user的信息,方法正常使用。
上面在消费者consumer-order
的方法中调用提供者provider-user
的方法的url
是写死的。
回顾:是把url
在配置文件中写死然后再通过@Value("${user.url}")
获取。
这里要动态获取到提供者的url
。
在消费者controller
中注入EurekaClient
,然后通过方法获取到对应服务的url
。
@RestController
public class OrderController {
@Autowired
private EurekaClient eurekaClient;
@Autowired
private RestTemplate restTemplate;//spring提供的一个用于访问rest接口的模板对象
//@Value("${user.url}")//去配置文件中去取值然后赋值给url
//private String url;
//private String url="http://localhost:7900/user/";
@GetMapping("/order/{id}")
public User getOrder(@PathVariable Long id){
InstanceInfo instanceInfo = eurekaClient.getNextServerFromEureka("PROVIDER-USER", false);
String url= instanceInfo.getHomePageUrl();
//访问提供者,获取数据
User user = restTemplate.getForObject(url + "/user/" + id, User.class);//通过访问rest获取到json数据,然后转换为user对象
return user;
}
}
然后运行EurekaServer
服务端,再分别启动提供者的客户端provider-user
和消费者的客户端consumer-order
的启动类,然后访问localhost:10000
,点击消费者服务的路径,重新编辑路径为http://laptop-oi5lg6ou:8900/order/2
,(2是id参数,重点不是2)回车访问,依然可以查看到user的信息。
Ribbon
是在消费者立场使用的。
复制一份消费者模块consumer-order
,改名为consumer-order-ribbon
,并导入项目。
操作说明:在idea中右键模块名,选择show in explorer
打开所在文件夹,然后复制重命名,需要更改pom文件中的模块名,然后idea自动把模块引入项目中,更改父项目的pom文件,就是添加一个
在consumer-order-ribbon
消费者的启动类加上注解@RibbonClient("PROVIDER-USER")
这个注解是启用ribbon,括号中为提供者的服务名,并对该服务provider-user
进行负载均衡。
@RibbonClient("PROVIDER-USER") //启用ribbon并对provider-user进行负载均衡
然后再orderController
中写方法,调用provider-user
服务的user/?
的方法,取得user的信息。
如下代码,在getForObject
方法中的url
路径参数,变为服务名,而不是上面的真实的路径地址。
@Autowired
private RestTemplate restTemplate;//spring提供的一个用于访问rest接口的模板对象
@GetMapping("/order/{id}")
public User getOrder(@PathVariable Long id){
//访问提供者,获取数据
User user = restTemplate.getForObject( "http://PROVIDER-USER/user/" + id, User.class);//通过访问rest获取到json数据,然后转换为user对象
return user;
}
启动项目,启动顺序(eureka服务端,provider-user提供者,ribbon消费者)
运行项目,进入到eureka中点击ribbon的服务地址,然后修改后面的路径为order/1,回车,可以查到user的信息。其实ribbon的作用最能体现的是把url
真实路径改为了服务名
给consumer-order-ribbon
消费者模块加上负载均衡算法
在consumer-order-ribbon
消费者模块写test方法,如果启动多个提供者模块的服务的话(改一个端口号另外启动),进到eureka
页面,点击consumer-order-ribbon
服务地址,然后修改为test路径,执行test方法,会看到后台打印出这几个提供者的服务名、ip地址、端口号,并且是轮询打印
。
@Autowired
private LoadBalancerClient loadBalancerClient;//注入负载均衡客户端
@GetMapping("/test")
public String test(){
ServiceInstance instance = loadBalancerClient.choose("PROVIDER-USER");//查找对应服务的实例,会通过负载均衡的算法返回一个实例
System.err.println(instance.getServiceId()+instance.getHost()+instance.getPort());
//可以查看这个实例的服务名,ip地址,端口号
return "1";
}
所以说,默认负载均衡算法是轮询算法。
写一个TestConfig
类写自定义负载均衡算法,也就是随机算法。
重点:这个TestConfig
类必须在启动类的包扫描范围之外,否则会报错
加注解@Configuration
标注成配置类
@Configuration
public class TestConfig {
@Autowired
IClientConfig iClientConfig;
/**
* 创建负载均衡算法的方法
* @Param config
*/
@Bean
public IRule rebbonRule(IClientConfig config){
return new RandomRule();//返回随机算法
}
}
然后在启动类上加注解@RibbonClient
,指定TestConfig
类文件
@RibbonClient(name="PROVIDER-USER",configuration = TestConfig.class) //启用ribbon并对provider-user进行负载均衡
在consumer-order-ribbon
消费者模块写test方法,如果启动多个提供者模块的服务的话(改一个端口号另外启动),进到eureka
页面,点击consumer-order-ribbon
服务地址,然后修改为test路径,执行test方法,可以看到后台是随机打印的
。
这样可以实现不同的服务去使用不同的负载均衡算法。
上面的是在TestConfig
配置类中通过注解@Bean
组件返回了一个随机算法,并在启动类上加上了注解@RibbonClient
启用ribbon
并指定TestConfig
配置类来进行负载均衡。
除了上面使用class文件配置Ribbon
,还可以通过application.yml
配置文件配置Ribbon
。
在consumer-order-ribbon
消费者模块的配置文件中配置,不配置默认是轮询算法。
PROVIDER-USER: # 服务名
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 给指定的服务配置负载均衡算法(随机算法)
在配置文件中配置禁用Ribbon
ribbon:
eureka:
enabled: false # 在eureka中禁用ribbon,禁用后需要自己负载均衡
Eureka Server 的高可用就是通过启动多个 Eureka Server 注册中心,让他们之间进行相互注册,达到共享注册信息的目的。这样就会都持有一份注册信息,即使其中一台挂掉了,其他的 Eureka Server 还在正常工作。
原本只有一个Eureka Server
服务注册中心,现在在原来的基础上,把服务注册中心模块的配置文件application.yml
删掉
创建配置文件application-peer1.yml
spring:
application:
name: eureka-ha
profiles:
active: peer1
server:
port: 8761
eureka:
instance:
hostname: peer1
client:
service-url:
defaultZone: http://peer2:8762/eureka/,http://peer3:8763/eureka/
创建配置文件application-peer2.yml
spring:
application:
name: eureka-ha
profiles:
active: peer2
server:
port: 8762
eureka:
instance:
hostname: peer2
client:
service-url:
defaultZone: http://peer1:8761/eureka/,http://peer3:8763/eureka/
创建配置文件application-peer3.yml
spring:
application:
name: eureka-ha
profiles:
active: peer3
server:
port: 8763
eureka:
instance:
hostname: peer3
client:
service-url:
defaultZone: http://peer2:8762/eureka/,http://peer1:8763/eureka/
通过spring.profiles.active
属性来分别启动peer1和peer2还有peer3(三个Eureka Server服务端)
此时
localhost:8761
,进入eureka页面,可以看到DS Replicas
处有了peer2和peer3localhost:8762
,进入eureka页面,可以看到DS Replicas
处有了peer1和peer3localhost:8763
,进入eureka页面,可以看到DS Replicas
处有了peer2和peer1 `Feign`是`Netflix`开发的声明式、模板化的HTTP客户端,` Feign`可以帮助我们更快捷、优雅地调用`HTTP API`。在`Spring Cloud`中,使用`Feign`非常简单——创建一个接口,并在接口上添加一些注解,代码就完成了。`feign`是声明式的web service客户端,它让微服务之间的调用变得更简单了,类似`controller`调用`service`。Spring Cloud集成了`Ribbon`和`Eureka`,可在使用Feign时提供负载均衡的http客户端。
Feign
也是在消费者的立场上使用的。
首先拷贝一份consumer-order
消费者模块并重命名为consumer-order-feign
,在pom文件添加feign
的依赖。
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-openfeignartifactId>
<version>1.4.3.RELEASEversion>
dependency>
然后在启动类上添加注解@EnableFeignClients
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class ConsumerOrder
{
public static void main( String[] args )
{
SpringApplication.run(ConsumerOrder.class);
}
}
创建一个接口,@FeignClient("provider-user")
注解指定哪个服务
@FeignClient("provider-user")//对应的消费者模块的服务名
public interface Client {
@RequestMapping(value = {"/user/{id}"})
User getOrder(@PathVariable("id") Long id);
}
然后把这个接口注入到controller
中
@RestController
public class OrderController {
@Autowired
private Client client;
@GetMapping("/order/{id}")
public User getOrder(@PathVariable Long id){
User user = client.getOrder(id);
return user;
}
}
运行项目,运行顺序(eureka服务端,provider-user提供者,consumer-order-feign消费者)
进入eureka页面,点击consumer-order-feign服务地址,修改链接为/order/1,可以得到user的信息。
在上面接口上面添加的注解@FeignClient("provider-user")
,修改为@FeignClient(name = "provider-user",configuration = Client.class)
,前面指定调用的消费者服务名,后面指定自定义配置文件名Client
。
新建一个config包,包里新建一个配置类,在这个配置类中对Feign
进行配置。
重点:这个Client
配置类必须在启动类的包扫描范围之外,否则会报错
@Configuration
public class FeignConfig {
@Bean
public Contract feignContract(){
return new feign.Contract.Default();
}
}
接口的写法
@FeignClient(name = "provider-user",configuration = Client.class)
public interface Client {
@RequestLine("GET /user/{id}") //Feign提供的组合注解,第一个是请求方式,第二个是参数用空格分隔
User getOrder(@Param("id") Long id);//注意使用@RequestLine注解的时候必须使用@Param注解
}
controller方法
@RestController
public class OrderController {
@Autowired
private Client client;
@GetMapping("/order/{id}")
public User getOrder(@PathVariable Long id){
User user = client.getOrder(id);
return user;
}
}
按顺序走?
EurekaServer
客户端provider-user
,该提供者的服务名为provider-user
Feign
,依赖,启动类注解,上边Feign
基本使用有controller
,把(4)的接口注入进来,并进行调用说明:访问Eureka
服务端,进入eureka页面,点击Feign
消费者的服务地址,修改路径为/order/1
,这个是(5)controller中方法的映射路径,在这个方法中调用(4)接口的方法,然后根据(4)接口的注解@FeignClient
和@RequestLine
指定的提供者的服务名和该服务的路径,然后调用提供者的具体的方法。
在上面的接口上的注解是
@FeignClient(name = "provider-user",configuration = Client.class)
可以使用url方式
@FeignClient(url="http://localhost:10000/",configuration = Client.class)
两者效果是相同的。
在Feign
客户端的application.yml
文件中加入配置开启日志
logging:
level: com.qianlong.Feign.Client # 给指定的Feign Client设置日志输入级别,只有在debug的情况下才会打印日志
在上面自定义配置时指定的配置类中加入日志的配置,配置要输出的日志有哪些,必须在debug模式下才可以输出。
@Bean
Logger.Level feignLoggerLevel(){
return Logger.Level.FULL;
}
分布式系统环境下,服务间类似依赖非常常见,一个业务调用通常依赖多个基础服务。如下图,对于同步调用,当库存服务不可用时,商品服务请求线程被阻塞,当有大批量请求调用库存服务时,最终可能导致整个商品服务资源耗尽,无法继续对外提供服务。并且这种不可用可能沿请求调用链向上传递,这种现象被称为雪崩效应。
举个例子,a服务需要远程调用b服务,b服务需要远程调用c服务,c服务远程调用d基础服务,如果d基础服务发生错误的话,那么c服务会一直连接d服务并且一直连不上,所以服务链上端的a,b服务只能一直等待,最后导致整条服务链不可用,这就是雪崩!讲的够生动了吧?
Hystrix
就是解决服务一直在等待导致雪崩的问题,它设置了每个服务去调用下一个服务时等待的时间,如果下一个服务发生错误的话,会到了指定的等待时间之后返回信息,并放弃连接,释放资源。
HyStrix
是在消费者的立场的。
首先复制一份消费者模块consumer-order
改名为consumer-order-hystrix
,并在pom
文件加入HyStrix
的依赖。
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-hystrixartifactId>
<version>1.4.3.RELEASEversion>
dependency>
然后在启动类上加上注解@EnableCircuitBreaker
,表示开启了熔断HyStrix
这个注解@EnableCircuitBreaker的作用,没有这个注解的话,假如c服务调用d服务时,d服务发生错误,c服务会直接执行失败后的回调方法,如果一直重复的发出请求,则会一直重复的请求两次,先是连接服务请求,请求失败后又进行回调;但是加上这个注解后,如果多次请求一个发生错误的服务时,会熔断效果,即不会再去尝试连接服务,而是直接进行失败后的回调方法。
最后回到远程调用提供者服务的controller
方法里面,在方法上面加上注解@HystrixCommand(fallbackMethod = "shibai")
,该注解表示,优先调用对应的提供者的服务,但是如果发生错误,就比如提供者模块没有启动,接口找不到,那么就会执行fallbackMethod
指定的回调方法,这样就不会造成长时间等待连接却连不上的问题。
@GetMapping("/order/{id}")
@HystrixCommand(fallbackMethod = "shibai")
public User getOrder(@PathVariable Long id){
InstanceInfo instanceInfo = eurekaClient.getNextServerFromEureka("PROVIDER-USER", false);
String url= instanceInfo.getHomePageUrl();
//访问提供者,获取数据
User user = restTemplate.getForObject(url + "/user/"+id, User.class);//通过访问rest获取到json数据,然后转换为user对象
return user;
}
/**
* 失败后进行的回调
* @param id
* @return
*/
public User shibai(Long id){
User user=new User();
user.setId(-100L);
user.setDate(new Date());
return user;
}
进行测试,启动服务,启动顺序(Eureka服务端
,消费者【consumer-order-hystrix】)没有提供者,进入Eureka页面,点击消费者地址,修改路径为order/1
,会返回
{"id":-100,"date":1568444848987}
回忆:Feign
是在消费者中使用接口远程调用提供者的接口,在接口中使用HyStrix
的fallback
回调。
复制一份consumer-order-feign
模块改名为consumer-order-feign-hystrix
,添加hystrix
依赖。
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-hystrixartifactId>
<version>1.4.3.RELEASEversion>
dependency>
在yml配置文件中开启Feign
的 HyStrix
。
feign:
hystrix:
enabled: true
然后就可以调用了。
在现在为止所有的微服务都是通过 Eureka 找到的,但是在很多的开发之中为了规范微服务的使用,提供有一个路由的处理控制组件:Zuul,也就是说 Zuul 就作为中间的一个代理层出现。
客户端想要请求到服务,首先请求到zuul网关,然后zuul网管将请求分发到对应的服务去。
新建一个模块apigateway-zuul
,加入依赖
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-securityartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-zuulartifactId>
<version>1.4.3.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
<version>1.4.3.RELEASEversion>
dependency>
启动类上加上注解@EnableZuulProxy
,注意一点,这里启动类的run方法中需要加上args。
@SpringBootApplication
@EnableZuulProxy //启用zuul,自带熔断和自动注册到eureka
public class ZuulApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulApplication.class,args);
}
}
然后写配置文件
server:
port: 10900 #程序启动后的端口
spring:
application:
name: apigateway-zuul #应用名称,别名
eureka:
client:
service-url:
defaultZone: http://user:123@localhost:10000/eureka
instance:
prefer-ip-address: true # 显示ip
# 配置访问zuul的routes(路由)的时候使用,不加也可以,但是麻烦,账号和密码会随机打印在控制台
security:
user:
name: user
password: abc
zuul是可以自动注册到eureka中的,启动项目,启动顺序(eurekaServer,提供者,apigateway-zuul),进入eureka页面,点击apigateway-zuul地址
修改路径为http://192.168.0.103:10900/提供者服务的名字(provider-user)/user/1
正常执行提供者中的user/1映射的方法。
上面路径是http://192.168.0.103:10900/provider-user/user/1
,provider-user是服务名,现在给指定服务做映射。
再配置文件中配置
zuul:
routes: # 配置路由映射
provider-user: /abc/** #给指定的服务做映射,比如当前是给provider-user添加映射地址为abc
那么启动项目之后,点击apigateway-zuul地址,访问路径就可以修改为
http://192.168.0.103:10900/abc/user/1
zuul会从eureka上找到所有的注册的服务,然后全部做代理,如果我们不想要它代理其中一些服务,只需要添加这个配置即可,如果是多个服务,以逗号分隔。
zuul:
routes: # 配置路由映射
provider-user: /abc/** #给指定的服务做映射,比如当前是给provider-user添加映射地址为abc
ignored-services: consumer-order # zuul会从eureka上找到所有的注册的服务,然后全部做代理,如果我们不想要它代理其中一些服务,只需要添加这个配置即可,如果是多个服务,以逗号分隔
访问http://192.168.0.103:10900/routes可以查看zuul代理的所有的服务。
给配置文件中加入配置
zuul:
routes: # 配置路由映射
abcdef: # 随便写,但是要保证是唯一的
path: /abcd/** # 映射的路径
serviceId: provider-user # 给那个服务做映射,这几行配置相当于前面的那一行配置
上面是path映射,下面说url映射,如果把path改成url映射的话,熔断和负载均衡将不再支持,因此需要在配置文件中配置ribbon
负载均衡。
zuul:
routes: # 配置路由映射
abcdef: # 随便写,但是要保证是唯一的
path: /abcd/** # 映射的路径
serviceId: provider-user # 给那个服务做映射,这几行配置相当于前面的那一行配置
ribbon:
eureka:
enabled: false # 在eureka中禁用ribbon的负载均衡
provider-user: # 给上面的serviceId对应的服务的名字指定一个ribbon的负载均衡,是从listOfServers配置的地址中选择
ribbon:
listOfServers: http://192.168.3.234:7900/,http://192.168.3.234:7901/
zuul:
prefix: /suibian
@Component
public class MyPreZuulFilter extends ZuulFilter {
/**
* 类型包含 pre post route error
* pre代表在路由代理之前执行
* route代表代理的时候执行
* error代表出现错的时候执行
* post代表在route或者是error执行完成后执行
* @return
*/
@Override
public String filterType() {
return "pre";
}
/**
* filter是一个链式调用,一个filter会调用下一个filter,如何知道顺序
* javaEE中是根据filter的配置先后顺序来决定
* zull是根据order决定,越小的越先执行
* @return
*/
@Override
public int filterOrder() {
return 0;
}
/**
* 是否使用这个过滤器
* @return
*/
@Override
public boolean shouldFilter() {
return false;
}
@Override
public Object run() {
System.out.println("过滤器执行了");
return null;
}
}
springCloud Config Server,统一配置中心,如果微服务架构中没有使用统一配置中心时,所存在的问题:
在SpringCloud中我们使用config组件来作为统一配置中心。
加上Config Server
依赖
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-config-serverartifactId>
<version>1.4.3.RELEASEversion>
dependency>
在启动类上面加上注解@EnableConfigServer
在配置文件中加入配置
server:
port: 12900 #程序启动后的端口
spring: # 配置 配置文件的仓库地址
cloud:
config:
server:
git:
uri: https://github.com/jackson/spring-cloud-config
前提是在github中存了一份配置文件,并把配置文件的路径写在uri里,这样项目就可以远程拿到并且使用配置文件中的内容了。
学习就到这里,springcloud只学习的话只是了解了什么是微服务和基本的使用,并不没有独立搭建微服务框架的能力,还是需要在工作中慢慢领悟,并一直学习总结才可以,一起努力吧兄弟盟!