spring cloud集群搭建以及Ribbon和Feign学习
上一篇文章讲述了单机环境的搭建,这一篇讲的是集群环境的搭建,其实改为集群是非常方便的
服务者的配置
server:
port: 7001
eureka:
instance:
hostname: eureka.7001.com #Eureka服务端的实例名称
client:
register-with-eureka: false # 表示是否向注册中心注册自己
fetch-registry: false # 表示如果为 false 表示自己为注册中心
service-url:
# defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ # 单机
defaultZone: http://eureka.7002.com:7002/eureka/,http://eureka.7003.com:7003/eureka/ # 集群(关联)
-----------------------------------------------------------------------
server:
port: 7002
eureka:
instance:
hostname: eureka.7002.com #Eureka服务端的实例名称
client:
register-with-eureka: false # 表示是否向注册中心注册自己
fetch-registry: false # 表示如果为 false 表示自己为注册中心com
service-url:
defaultZone: http://eureka.7001.com:7001/eureka/,http://eureka.7003.com:7003/eureka/ # 集群(关联)
------------------------------------------------------------------------
server:
port: 7003
eureka:
instance:
hostname: eureka.7003.com #Eureka服务端的实例名称
client:
register-with-eureka: false # 表示是否向注册中心注册自己
fetch-registry: false # 表示如果为 false 表示自己为注册中心
service-url:
defaultZone: http://eureka.7001.com:7001/eureka/,http://eureka.7002.com:7002/eureka/ # 集群(关联)
这个时候就用到之前配置的host文件了,因为我们只有一台电脑,就配置了3个域名都访问本机
这是3个项目的配置,其实改动的就只有 defaultZone这里,会把自己除外的其他注册中心添加进来
如下图所示:
这个时候我们有了3个注册中心和一个服务,我们接下来启动3个服务
服务者配置
server: port: 8001 mybatis: mapper-locations: classpath:mapper/*Mapper.xml type-aliases-package: com.xd.springcloud.pojo configuration: cache-enabled: true spring: application: name: springcloud-provider-dept datasource: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: org.gjt.mm.mysql.Driver url: jdbc:mysql://localhost:3306/db01?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&failOverReadOnly=false&allowMultiQueries=true&useSSL=false username: root password: root eureka: client: service-url: defaultZone: http://eureka.7001.com:7001/eureka/,http://eureka.7002.com:7002/eureka/,http://eureka.7003.com:7003/eureka/ instance: instance-id: springcloud-provider-dept-8001 # 修改默认的描述信息 info: # 单纯的给 eureka 一些信息 app.name: xd-springcloud company.name : LTIL --------------------------------------------------------------------- server: port: 8003 mybatis: mapper-locations: classpath:mapper/*Mapper.xml type-aliases-package: com.xd.springcloud.pojo configuration: cache-enabled: true spring: application: name: springcloud-provider-dept datasource: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: org.gjt.mm.mysql.Driver url: jdbc:mysql://localhost:3306/db02?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&failOverReadOnly=false&allowMultiQueries=true&useSSL=false username: root password: root eureka: client: service-url: defaultZone: http://eureka.7001.com:7001/eureka/,http://eureka.7002.com:7002/eureka/,http://eureka.7003.com:7003/eureka/ instance: instance-id: springcloud-provider-dept-8003 # 修改默认的描述信息 info: app.name: xd-springcloud company.name : LTIL ------------------------------------------------------------------ server: port: 8004 mybatis: mapper-locations: classpath:mapper/*Mapper.xml type-aliases-package: com.xd.springcloud.pojo configuration: cache-enabled: true spring: application: name: springcloud-provider-dept datasource: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: org.gjt.mm.mysql.Driver url: jdbc:mysql://localhost:3306/db03?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&failOverReadOnly=false&allowMultiQueries=true&useSSL=false username: root password: root eureka: client: service-url: defaultZone: http://eureka.7001.com:7001/eureka/,http://eureka.7002.com:7002/eureka/,http://eureka.7003.com:7003/eureka/ instance: instance-id: springcloud-provider-dept-8004 # 修改默认的描述信息 info: app.name: xd-springcloud company.name : LTIL
可以看到基本上的配置信息都是一样的要注意的点是我配置的三个数据源都是不同,而且 spring application 的name 是一定要相同的 这个代表了是同一个服务
然后把3个服务中心的Ip都配置进去,以后有几个配置几个
启动服务者
可以看到服务者变成了三个
接下来我们要使用Ribbon做一些配置
我们自己注册一个 Bean
@Configuration public class ConfigBean { // 配置负载均衡 实现 RestTemplate // IRule // RandomRule 随机 // RoundRobinRule 轮询 // RetryRule 会先按照轮询获取服务 如果服务获取失败 会在指定的时间内进行重试 // WeightedResponseTimeRule 权重 // AvailabilityFilteringRule 会先过滤掉跳闸的服务 对剩下的进行轮询 @Bean @LoadBalanced // Ribbon public RestTemplate getRestTemplate() { return new RestTemplate(); } }
接下来我们要在启动类的同级建一个包,因为这样可以在需要的时候使用,如果放在application目录下的话,将所有都会使用这个策略
新建一个 Bean
@Configuration public class XdRule { @Bean public IRule myRule(){ return new XdRandomRule();// 默认是轮询 可以自定义自己的 } }
这个其实不是自定义的 其实是官方随机的算法 我自己懒的写了
public class XdRandomRule extends AbstractLoadBalancerRule { public Server choose(ILoadBalancer lb, Object key) { if (lb == null) { return null; } Server server = null; while (server == null) { if (Thread.interrupted()) { return null; } List<Server> upList = lb.getReachableServers();// 获得还活着的服务 List<Server> allList = lb.getAllServers();// 获得全部的服务 int serverCount = allList.size(); if (serverCount == 0) { return null; } int index = chooseRandomInt(serverCount); // 生成区间随机数 server = upList.get(index);// 从活着的服务中随机获取一个 if (server == null) { Thread.yield(); continue; } if (server.isAlive()) { return (server); } server = null; Thread.yield(); } return server; } protected int chooseRandomInt(int serverCount) { return ThreadLocalRandom.current().nextInt(serverCount); } @Override public Server choose(Object key) { return choose(getLoadBalancer(), key); } @Override public void initWithNiwsConfig(IClientConfig clientConfig) { // TODO Auto-generated method stub } }
这个时候访问消费者 就会随机从3个服务中获得数据
接下来是使用feign 用接口的方式调用服务
maven依赖
<dependencies> <!-- feign --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> <version>1.4.6.RELEASE</version> </dependency> <!-- ribbon--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> <version>1.4.6.RELEASE</version> </dependency> <!-- erueka--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> <version>1.4.6.RELEASE</version> </dependency> <dependency> <groupId>com.xd</groupId> <artifactId>springcloud-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> </dependency> </dependencies>
配置是非常简单的 因为现在这里是在消费者这里配置了
server:
port: 80
eureka:
client:
register-with-eureka: false # 不向注册中心注册自己
service-url:
defaultZone: http://eureka.7001.com:7001/eureka/,http://eureka.7002.com:7002/eureka/,http://eureka.7003.com:7003/eureka/
我们需要在之前的实体类项目中新建service
@Component @FeignClient(value = "SPRINGCLOUD-PROVIDER-DEPT") public interface DeptClientService { @RequestMapping("/dept/add") public boolean addDept(Dept dept); @RequestMapping("/dept/queryById/{id}") public Dept queryById(Long id); @RequestMapping("/dept/queryAll") public List<Dept> queryAll(); }
然后消费者的controller修改成这样
@RestController public class DeptConsumerController { @Autowired private DeptClientService service = null; @RequestMapping("/consumer/dept/add") public boolean addDept(Dept dept) { return this.service.addDept(dept); } @RequestMapping("/consumer/dept/queryById/{id}") public Dept queryById(@PathVariable Long id) { return this.service.queryById(id); } @RequestMapping("/consumer/dept/queryAll") public List<Dept> queryAll() { return this.service.queryAll(); } }
不在需要 Rest Template
这是我的项目地址下载之后配置数据库就可以直接用
https://files.cnblogs.com/files/beastGentleman/springCloud.zip