自学多日,写一个demo做个总结,从建项目开始,比较简单的实现spring cloud微服务,上一篇写了Eureka服务,生产者消费者,RestFul调用,Hystrix容错机制,第二篇写Ribbon实现负载均衡,建立zuul网关,供初学者参考,更快的理解spring cloud
win10
Idea2019.3
jdk1.8.0_241
spring boot 2.2.7
spring cloud Hoxton.SR4
根据官网伦敦车站命名法提示,Hoxton站对应springboot 2.2.X,所以选择2.2.7
第一篇写了,四个子项目,服务,消费者,生产者,公共实体类
第二篇追加两个模块
修改一下provider
加一个count参数,加一段log,被调用时,打印方法名和count编号
package com.sunc.provideruser.controller;
import com.sunc.bean.Users;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;
@RestController
public class UserController {
private Logger logger = LoggerFactory.getLogger(UserController.class);
@RequestMapping(value = "userp",method = RequestMethod.POST)
public Integer getUser(@RequestBody Users user, @RequestParam("count") Integer count){
logger.info("this is provideruser, count: "+count);
Integer i = 0;
if ("xiaobai".equals(user.getUser_name()) && "123".equals(user.getPass_word())){
i = 1;
}
return i;
}
}
修改一下consumer
加一个参数i,让provider知道他是被第几次调用
package com.sunc.consumeruser.controller;
import com.sunc.bean.Users;
import com.sunc.consumeruser.service.UserService;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
@Autowired
private UserService userService;
@RequestMapping(value = "/userc",method = RequestMethod.GET)
public String getUser(@RequestParam("name") String name, @RequestParam("pass") String pass){
Users users = new Users();
users.setUser_name(name);
users.setPass_word(pass);
String res = "";
// if(userService.getUser(users).equals(1)){
// res = "hello "+users.getUser_name()+", this is consumer";
// } else if (userService.getUser(users).equals(0)){
// res = "Sorry, user name or password is wrong ~~";
// } else if (userService.getUser(users).equals(2)){
// res = "Sorry, 服务器挂了 ~~";
// }
for (int i = 0; i < 20 ; i++) {
userService.getUser(users,i)
}
return res;
}
}
修改一下service
加一个参数Integer count,传到provider去,熔断器可以注释掉,也可以加一个Integer 防止报错
package com.sunc.consumeruser.service;
import com.sunc.bean.Users;
import com.sunc.consumeruser.service.Impl.UserServiceFallback;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(name = "provider-user", fallback = UserServiceFallback.class)
public interface UserService {
@RequestMapping(value = "/userp",method = RequestMethod.POST)
public Integer getUser(@RequestBody Users user,@RequestParam("count") Integer count);
}
确定两个客户端都注册进来
http://localhost:4462/userc?name=xiaobai&pass=123
可以看到log显示,20次循环调用都进入provider中,修改结束
实现负载均衡有两种方法
第一种是通过服务端来选择是哪一个服务端来负载客户端的请求,就是通过nginx配置
第二种是通过客户端来选择哪一个服务端来负载请求,就是Ribbon
复制一个provider-user,目的是用两个provider实现相同功能,共同承担consumer的请求
provider-user-1
直接ctrl+c,ctrl+v,名字改成provider-user-1
修改iml文件名和文件夹名相同
pom中名字改成对应的provider-user-1
导入provider-user-1
如果出现两个,provider-user-1.iml和provider-user(1).iml
将provider-user-1.iml中所有内容复制到provider-user(1).iml中,然后provider-user-1.iml删除,provider-user(1).iml改成provider-user-1.iml。
修改端口号
4463,但是application.name名字不变,依然叫provider-user,consumer找provider只认识provider-user,具体是哪一个provider负责服务,跟consumer没关系。
启动
可以看到,此时4463已经注册,形成生产者消费者1V2的局面
修改consumer配置文件
追加一条均衡策略,下面截图中可以看到轮询和随机,官网还有不少没写全
provider-user为客户端名字,只针对provider-user设置负载均衡策略
provider-user.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RoundRobinRule
重启consumer
访问接口
http://localhost:4462/userc?name=xiaobai&pass=123
此时可以看到端口号4461,打印了13579…,端口号4463,打印了02468…,两个服务共同服务了consumer的20次请求
server.port=4464
spring.application.name=zuul-server
eureka.client.service-url.defaultZone=http://localhost:4460/eureka
zuul.routes.consumer-user.path=/userapi/**
启动类
package com.sunc.zuulserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
@SpringBootApplication
@EnableDiscoveryClient
@EnableZuulProxy
public class ZuulServerApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulServerApplication.class, args);
}
}
启动项目
可以看到已经注册进来
访问接口
http://localhost:4464/userapi/userc?name=xiaobai&pass=123
注意接口多了一个userapi
两篇帖子,做到这实现了,eureka服务,生产者,消费者搭建,消费者对生产者的调用,共用同一个实体类,消费者挂机时容错机制。生产者消费者1V2,Ribbon负载均衡,zuul网关
如有偏颇敬请斧正,本厮邮箱:[email protected]