Springcloud 微服务集群通信(一)

主要内容:

  1. 不同服务之间如何通信,传递什么
  2. Ribbon是什么,怎么集成
  3. Feign是什么,怎么集成
  4. Hystrix是什么,怎么集成(和Ribbon、Feign),以及这两者区别
  5. Zuul是什么,怎么集成

不同服务之间的通信

现在要做springboot-pay-server(支付服务)与springboot-user-server(用户服务)之间的通信

1.新创建一个springcloud-user-common公共访问模块

提供一个公共可访问的domain:User

2.springcloud-producer-user-server-1000用户端暴露接口

对外暴露一个接口(Controller):

@RestController
public class UserController {

    //pay-server来调用
    //@RequestMapping(value = "/user",method = "GET")
    //localhost:port/user/11
    //PathVariable将URL 中占位符参数绑定到控制器处理方法的入参中
    @GetMapping(value = "/user/{id}")
    public User getUserById(@PathVariable("id") Long id){
        return new User(id,"zs:"+id,"wo shi zs : port=1000");
    }
}

访问这个接口:
在这里插入图片描述

3.springcloud-consumer-pay-server-2000支付端暴露接口

支付端应该远程调用客户端来获取其user对象而不是再new一个user出来
需要用到RestTemplate:一个spring封装的http工具

PayController :
@RestController
public class PayController {
    @Autowired
    private RestTemplate restTemplate;
    @GetMapping("/pay/user/{id}")
    public User pay(@PathVariable("id") Long id){
        //远程调用user-server获取user对象并返回 : 在Java代码中发送http请求 - RestTemplate
        String url = "http://localhost:1000/user/"+id;
        return restTemplate.getForObject(url,User.class);
    }
}
PayServerApplication2000 :
@SpringBootApplication
public class PayServerApplication2000
{
    public static void main( String[] args )
    {
        SpringApplication.run(PayServerApplication2000.class);
    }
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

在这里插入图片描述

Ribbon集成

ribbon是负载均衡器,是基于RestTemplate ,它赋予了RestTemplate 负载均衡的能力

1.复制一个springcloud-producer-user-server-1000,并修改端口为1001

在这里插入图片描述
两台相同的服务(端口号不同)是为了后面的支付模块(springcloud-consumer-pay-server-2000)来调用

2.支付端springcloud-consumer-pay-server-2000集成Ribbon
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </dependency>
3.修改支付模块启动类

@LoadBalanced让RestTemplate具有负载均衡的能力

@SpringBootApplication
public class PayServerApplication2000
{
    public static void main( String[] args )
    {
        SpringApplication.run(PayServerApplication2000.class);
    }
    @LoadBalanced
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}
4.修改支付模块暴露接口

原先是localhost:1000,由于在appliction中指定了服务名

spring:
  application:
    name: user-server

并且有两个(服务相同,端口不同)
所以进行替换,让Ribbon按某种规则去选择一个服务去执行

@RestController
public class PayController {

    @Autowired
    private RestTemplate restTemplate;
    @GetMapping("/pay/user/{id}")
    public User pay(@PathVariable("id") Long id){
        String url = "http://user-server/user/"+id;
        return restTemplate.getForObject(url,User.class);
    }
}
5.负载均衡规则

随机均衡算法:

@SpringBootApplication
public class PayServerApplication2000
{
    public static void main( String[] args )
    {
        SpringApplication.run(PayServerApplication2000.class);
    }

    @LoadBalanced
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

    @Bean
    public IRule randomRule(){
        return new RandomRule();
    }
}

Feign集成

Feign是一个声明式的Web Service客户端,它的目的就是让Web Service调用更加简单。Feign提供了HTTP请求的模板,通过编写简单的接口和插入注解,就可以定义好HTTP请求的参数、格式、地址等信息。而Feign则会完全代理HTTP请求,我们只需要像调用方法一样调用它就可以完成服务请求及相关处理。Feign整合了Ribbon和Hystrix(关于Hystrix我们后面再讲),可以让我们不再需要显式地使用这两个组件。

1.新建一个springcloud-consumer-order-server-4000模块

导包修改端口

2.修改启动类
@SpringBootApplication
//作用是开启支持和指定接口
@EnableFeignClients({"cn.itsource.feignclients"})
public class OrderServerApplication4000
{
    public static void main( String[] args )
    {
        SpringApplication.run(OrderServerApplication4000.class);
    }
}
3.创建接口

这个接口中的方法就是用来调用目标服务中的方法

//指定这个接口要访问那个服务名,这个服务名是对应一个端口+ip的
//Fiegn通过服务名user-server就能从注册中心到要调用的目标服务,根据方法上的url就能够找到目标服务的具体的Controller,就相当于拼接了一个url:http://user-server/user/11
@FeignClient(value = "user-server")
public interface UserFeignClient {
	//参数类型、返回值、url要和@FeignClient注解指定的服务中的对应方法一致
    @GetMapping(value = "/user/{id}")
    User getUserById(@PathVariable("id") Long id);
}

集成Hystrix

解决服务器故障(雪崩)的一个组件 ,它可以实现:隔离 ,熔断 ,降级,缓存

  1. 隔离 :包括线程池隔离和信号量隔离,限制调用分布式服务的资源使用,某一个调用的服务出现问题不会影响其他服务调用。
  2. 熔断 :当请求次数达到规定的阀值都出现服务故障(超时),Hystrix就把服务标记为短路状态.
    正常情况下,断路器处于关闭状态(Closed),如果调用持续出错或者超时,电路被打开进入熔断状态(Open),后续一段时间内的所有调用都会被拒绝(Fail Fast),一段时间以后,保护器会尝试进入半熔断状态(Half-Open),允许少量请求进来尝试,
    如果调用仍然失败,则回到熔断状态
    如果调用成功,则回到电路闭合状态;
  3. 降级 :高并发情况下 ,为了保证一些主要的服务有足够的资源不出问题 ,会认为的关掉一些无关紧要的服务,然后返回一些托底的数据,给用户一个友好的提示。
  4. 缓存 :Hystrix内部会把请求做缓存
1.在哪儿集成

应该在支付端集成,因为支付端会去调用用户端的数据,用户端的服务是可以人为关闭的,关闭了的话集成Hystrix也没有效果

2.Ribbon集成Hystrix
  1. 导包
  2. 主启动类加上@EnableCircuitBreaker开启熔断机制
  3. Controller中创建托底方法
3.Feign集成Hystrix

已经集成了,我们只需要开启就好了

  1. 在application.yml中:
#开启hystrix服务
feign:
  hystrix:
    enabled: true
  1. 在@FeignClient标签,指定fallback属性指定托底类
@FeignClient(value = "user-server", fallback = UserFeignClientFallback.class)
public interface UserFeignClient {

    //要调用的服务的Controller中的方法,建议直接拷贝过来:
    //1.url要一样 , 2参数要一样 , 3返回值要一样
    @GetMapping(value = "/user/{id}")
    User getUserById(@PathVariable("id") Long id);
}
  1. 编写托底类:注意拖地类要实现Feign接口 ,复写方法实现拖地数据,注意加上@Component
@Component
public class UserFeignClientFallback implements UserFeignClient {
    @Override
    public User getUserById(Long id) {
        return new User(-1L,"无此用户","用户服务不可用");
    }
}

Ribbon与Feign集成Hystrix的区别
前者是在Controller需要熔断的方法上加@HystrixCommand(fallbackMethod = “payFallback”)从而指定托底方法,这个托底方法就可以写在Controller中。
而后者是在用来调用user-server的客户端接口UserFeignClient处指定熔断类:fallback = UserFeignClientFallback.class,让这个被指定的类帮我们返回托底方法。

zuu的集成

在这里插入图片描述
zuu在云平台上提供动态路由、监控、弹性、安全等服务,相当于Web网站后端所有请求的前门,要注册到注册中心

1.新建一个模块springcloud-zuul-server-5000
2.导包
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>
3.在配置文件application中指定zuul的注册中心
4.修改主启动类
@SpringBootApplication
//开启zuul
@EnableZuulProxy
public class ZuulServerApplication5000
{
    public static void main( String[] args )
    {
        SpringApplication.run(ZuulServerApplication5000.class);
    }
}
5.配置路由

不配置路由的话可以绕过zuul,直接去访问需要的资源
并且现在我们是直接访问的服务名

1.禁用服务名访问方式
zuul:
  ignored-services: "*" #禁止浏览器 使用服务名的方式去访问目标服务
2.指定服务用什么名字取访问

可以理解为起别名,达到隐藏服务名的作用

zuul:
  routes:
    pay-server: "/pay/**" # pay-server这个服务使用 /pay路径去访问
    order-server: "/order/**" #order-server这个服务使用 /order 路径去访问
    # http://localhost:5000/hrm/pay/pay/user/20 :访问方式: zuulip:zuul端口/前缀/服务的访问路径/资源路径
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值