Spring Cloud Ribbon LoadBalance Gateway

0.补充内容

对于注册中心的客户端使用@EnableEurekaClient@EnableDiscoveryClient的区别做补充:
1.二者都可以表示申明为Eureka注册中心的客户端
2.不同@EnableDiscoveryClient还可以用于支持别的类型的注册中心,而@EnableEurekaClient仅仅是Eureka注册中心对应的客户端申明。

1. 提供服务的客户端(user-service × n,n≥2)

直接贴代码pom.xml

<dependency>
	<groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

配置项application.yml

spring:
  application:
    name: user-service
server:
  port: 8201
eureka:
  client:
    service-url:
      deafultZone: http://localhost:8761/eureka
    register-with-eureka: true
    fetch-registry: true

提供服务的controller

@RestController
@RequestMapping("/user")
public class UserController {

    private Logger logger  = LoggerFactory.getLogger(UserController.class);

    @Autowired
    private UserService userService;

    @PostMapping("/create")
    public CommonResult create(@RequestBody User user){
        userService.create(user);
        return new CommonResult("操作成功",200);
    }

    @GetMapping("/{id}")
    public CommonResult<User> getUser(@PathVariable Long id){
        User user = userService.getUser(id);
        logger.info("根据id获取用户信息,用户名称为:{}",user.getUsername());
        return new CommonResult<>(user);
    }

    @GetMapping("/getUserByIds")
    public CommonResult<List<User>> getUserByIds(@RequestParam List<Long> ids){
        List<User> userList= userService.getUserByIds(ids);
        logger.info("根据ids获取用户信息,用户列表为:{}",userList);
        return new CommonResult<>(userList);
    }
    @GetMapping("/getByUsername")
    public CommonResult<List<User>> getByUsername(@RequestParam String username) {
        List<User> users = userService.getByUsername(username);
        return new CommonResult<>(users);
    }

    @PostMapping("/update")
    public CommonResult update(@RequestBody User user) {
        userService.update(user);
        return new CommonResult("操作成功", 200);
    }

    @PostMapping("/delete/{id}")
    public CommonResult delete(@PathVariable Long id) {
        userService.delete(id);
        return new CommonResult("操作成功", 200);
    }
}

其他代码见附录

2. Ribbon-Service

pom.xml

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <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-netflix-ribbon</artifactId>
        </dependency>

配置文件 application.yml

spring:
  application:
    name: ribbon-service

server:
  port: 8001
eureka:
  client:
    fetch-registry: true
    register-with-eureka: true
    service-url:
      defaltZone: http://localhost:8761/eureka/
service-url:
  user-service: http://user-service #此处为自定义的配置

Spring Cloud 中 某客户端服务向注册中心访问其他服务时通过以下url访问:
http://{service-name}
其中service-name是指服务向注册中心注册时所提供的名称(即ID),一般是application.yml中配置的{spring.application.name}项。

注册由Ribbon提供的某负载均衡策略Bean

@Configuration
public class RibbonConfig {
    @Bean
    @LoadBalanced //这里指定策略,还有其他的策略
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

Ribbon-Service 提供的网关接口
controller

@RestController
@RequestMapping("/user")
public class UserServiceRibbonController {

    @Autowired
    private RestTemplate restTemplate;

    @Value("${service-url.user-service}")
    private String userServiceUrl;

    @GetMapping("/{id}")
    public CommonResult getUser(@PathVariable Long id){
        return restTemplate.getForObject(userServiceUrl+"/user/{1}",CommonResult.class,id);
    }

    @GetMapping("/getByUsername")
    public CommonResult getByUsername(@RequestParam String username){
        return restTemplate.getForObject(userServiceUrl+"/user/getByUsername?username={1}",
                CommonResult.class,username);
    }

    @GetMapping("/getEntityByUsername")
    public CommonResult getEntityByUsername(@RequestParam String username){
        ResponseEntity<CommonResult> resultResponseEntity =
                restTemplate.getForEntity(userServiceUrl+"/user/getByUsername?username={1}",
                        CommonResult.class,username);
        if(resultResponseEntity.getStatusCode().is2xxSuccessful()){
            return resultResponseEntity.getBody();
        }
        return new CommonResult("操作失败",500);
    }

    @PostMapping("/create")
    public CommonResult create(@RequestBody User user){
        return restTemplate.postForObject(userServiceUrl+"/user/create",
                user,CommonResult.class);
    }

    @PostMapping("/update")
    public CommonResult update(@RequestBody User user){
        return restTemplate.postForObject(userServiceUrl+"/user/update",
                user,CommonResult.class);
    }

    @PostMapping("/delete/{id}")
    public CommonResult delete(@PathVariable Long id){
        return restTemplate.postForObject(userServiceUrl+"/user/delete/{id}",
                null,CommonResult.class,id);
    }

}

其余代码见附录

3. 使用

  1. 启动eureka-service注册中心(见上一节)
  2. 分别在两个端口启动user-service服务,
  3. 启动ribbon-service服务
  4. 使用 http://localhost:8001/user/1多次访问,会发现是轮流访问两个user-service

附录(其他相关代码)

1.userService
@Service("userServiceImpl")
public class UserServiceImpl implements UserService {
    private List<User> userList;

    @Override
    public void create(User user) {
        userList.add(user);
    }

    @Override
    public User getUser(Long id) {
        List<User> findUserList = userList.stream().filter(
                userItem -> userItem.getId().equals(id)
        ).collect(Collectors.toList());
        if (! findUserList.isEmpty()){
            return findUserList.get(0);
        }
        return null;
    }

    @Override
    public void update(User user) {
        userList.stream().filter(u -> u.getId().equals(user.getId()))
                .forEach(u -> u.clone(user) );
    }

    @Override
    public void delete(Long id) {
        User u = null;
        if( (u=getUser(id)) != null){
            userList.remove(u);
        }
    }

    @Override
    public List<User> getByUsername(String username) {
        List<User> ret = userList.stream().filter(
                u -> u.getUsername().equals(username)
        ).collect(Collectors.toList());
        if(! ret.isEmpty()){
            return ret;
        }
        return null;
    }

    @Override
    public List<User> getUserByIds(List<Long> ids) {
        List<User> ret = userList.stream().filter(
                u -> ids.contains(u.getId())
        ).collect(Collectors.toList());
        if(! ret.isEmpty()){
            return ret;
        }

        return null;
    }

    @PostConstruct
    public void initData() {
        userList = new ArrayList<>();
        userList.add(new User(1L, "macro", "123456"));
        userList.add(new User(2L, "andy", "123456"));
        userList.add(new User(3L, "mark", "123456"));
    }

}
2. CommonResult
public class CommonResult<T> {
    private T data;
    private String message;
    private Integer code;

    public CommonResult() {
    }

    public CommonResult(T data, String message, Integer code) {
        this.data = data;
        this.message = message;
        this.code = code;
    }

    public CommonResult(String message, Integer code) {
        this(null, message, code);
    }

    public CommonResult(T data) {
        this(data, "操作成功", 200);
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }
}
3. User
public class User {
    private Long id;
    private String username;
    private String password;
    public User(){

    }
    public User(Long id, String userName, String password) {
        this.id = id;
        this.username = userName;
        this.password = password;
    }


    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public void clone(User u){
        this.setUsername(u.getUsername());
        this.setPassword(u.getPassword());
        this.setId(u.getId());

    }
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值