欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

springcloud系列(3) - ribbon的使用

程序员文章站 2022-06-22 16:17:54
...

首先也是基于前面两个博客的继续往下写的

在使用ribbon之前,先介绍下ribbon,ribbon是客户端负载均衡,就是说,每一个微服务都会将eureka注册中心的信息获取存在本地,然后调用的时候使用一定的算法进行调用(各种算法,比如轮询,随机等)

负载均衡肯定要讲下ngnix,这个是服务端负载均衡,就是说,请求转发给ngnix服务器,然后由ngnix服务器来帮你转发(基于相关的配置,但是这个只适合于单模块多实例的服务,不适合多模块的微服务,如果要使用ngnix在多模块中,那么相当于每个模块都要配置一个ngnix服务器进行负载均衡)

 

一样的,首先创建一个order-service订单服务,pom.xml同样不需要引入什么,因为父工程中已经有了。

在resource中创建application.yml文件,内容:

spring:
  application:
    name: order-service

server:
  port: 8801

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8888/eureka/
  instance:
    prefer-ip-address: true

创建包名和OrderServiceApplication.java 

@SpringBootApplication
@EnableDiscoveryClient
public class OrderServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderServiceApplication.class,args);
    }
}

然后创建ribbon的配置类:RestTemplateConfig.java

@Configuration  //标明是配置类
public class RestTemplateConfig {

    @Bean // 放入spring容器中管理
    @LoadBalanced // 开启负载均衡,如果没有这个那么将不能通过微服务的名称去调用别的服务,但可以通过ip和端口号去调用
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

现在首先要实现远程调用,举个列子: 使用订单服务去调用用户服务获取用户的信息

首先在用户模块(user-service)创建一个接口controller: UserController:

@RequestMapping("/v1")
@Controller
public class UserController {

    @RequestMapping(value = "/user")
    public ResponseEntity<?> getUserInfo(){
        UserInfoResp userInfos= new UserInfoResp();
        userInfos.setNickName("cara liu0");
        userInfos.setPk(1L);
        userInfos.setPhoneNumber("18814098957");
        return new ResponseEntity<>(userInfos, HttpStatus.OK);
    }
}

UserInfoResp.java:

package cn.yishijie.apibean.v1;

/**
 * @author jeffchan 2020/03/10
 */
public class UserInfoResp {

    private long pk;
    private String nickName;
    private String phoneNumber;

    public long getPk() {
        return pk;
    }

    public void setPk(long pk) {
        this.pk = pk;
    }

    public String getNickName() {
        return nickName;
    }

    public void setNickName(String nickName) {
        this.nickName = nickName;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }
}

跑起来看能不能调通接口: 调用 GET http://localhost:8800/v1/user 

返回信息: 

{

"pk": 1,

"nickName": "cara liu0",

"phoneNumber": "18814098957"

}

接口没问题了,那么接着就是写订单服务那边的代码:创建 OrderController

@Controller
@RequestMapping("/v1")
public class OrderController {


    @Autowired
    private RibbonUserService ribbonUserService;
    @RequestMapping(value = "/order",method = RequestMethod.GET)
    public ResponseEntity<?> getOrder(){
        UserInfoResp userInfoResp = ribbonUserService.getUserInfo();
        return new ResponseEntity<>(userInfoResp, HttpStatus.OK);
    }
}

创建 RibbonUserService 和 相应实现类:RibbonUserServiceImpl ,同样需要上述的UserInfoResp(直接拷贝上述的即可)类:

public interface RibbonUserService {

    UserInfoResp getUserInfo();
}
@Service
public class RibbonUserServiceImpl implements RibbonUserService {

    @Autowired
    private RestTemplate restTemplate;
    @Override
    public UserInfoResp getUserInfo() {
        UserInfoResp userInfoResp = null;
        String url = "http://USER-SERVICE/v1/user";
        try {
            //远程调用
            ResponseEntity<UserInfoResp> result =  restTemplate.getForEntity(url,UserInfoResp.class);
            userInfoResp = result.getBody();
        }catch (Exception e){
            System.out.println(e.getMessage());
        }
        return userInfoResp;
    }
}

启动项目,访问 GET http://localhost:8801/v1/order  返回结果跟用户服务是一样的。

 

验证ribbon的默认负载均衡规则

copy一个用户模块,修改端口号,同时修改用户的昵称为 cara liu1(为了验证调用的是不同的实列)启动即可:如下图

springcloud系列(3) - ribbon的使用

有了两个实列,然后你调用订单的那个接口,发现会轮询的返回不同的昵称

当然也可以修改这个规则,注入一个对应的IRule类型的实列即可(可以使用依赖中已经提供的策略,也可以自己定义,同时还可以为特定的一个微服务提供一个特定的规则,比如说我订单服务还要调用其他直播服务啥的,那么可以为分别为用户服务和直播服务设置不同的均衡规则)

相关标签: springcloud