上一篇写到关于SpringCloudEureka的相关知识:SpringCloud服务治理Eureka。咱们实现的服注册中心,以及服务提供者。接下来记录关于服务消费,以及客户端负载均衡器Ribbon的简单使用和配置。在使用Ribbon以前,先看看怎么调用服务吧。java
在上一篇的基础之上,建立一个service-user
的微服务。这个微服我使用了h2数据库来保存数据,因此须要在配置文件中添加关于数据库的配置以及在pom文件中添加依赖,<!--more-->
application.ymlgit
server: port: 40000 spring: application: name: user-service #=========================================================== # 数据库配置 #=========================================================== jpa: show-sql: true hibernate: ddl-auto: none generate-ddl: false datasource: platform: h2 schema: classpath:schema.sql data: classpath:data.sql #=========================================================== # eureka配置 #=========================================================== eureka: client: serviceUrl: defaultZone: http://localhost:8888/eureka/ instance: prefer-ip-address: true instance-id: ${spring.application.name}:${server.port}
pom.xmlweb
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency> </dependencies>
而后编写数据库文件初始化数据;
schema.sqlspring
DROP TABLE user if EXISTS ; create table user ( id int generated by DEFAULT as IDENTITY, username VARCHAR (40), age INT(3), PRIMARY KEY (id) );
data.sqlsql
insert into user (id,username,age) values (1,'张三',20); insert into user (id,username,age) values (2,'李四',25); insert into user (id,username,age) values (3,'王五',23); insert into user (id,username,age) values (4,'赵六',30);
User实体类,这里使用了lombok
工具数据库
@Entity @Data public class User implements Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; @Column private String username; @Column private int age; }
而后建立UserRepository
和UserController
,在UserController
中添加一个根据id查询的接口:app
@Autowired private UserRepository userRepository; @GetMapping("/user/{id}") public User findById(@PathVariable("id") Long id){ return userRepository.findOne(id); }
在SpringBoot
入口类上添加@EnableEurekaClient
注解负载均衡
@EnableEurekaClient @SpringBootApplication public class UserApplication { public static void main(String[] args) { SpringApplication.run(UserApplication.class, args); } }
最终的项目结构:dom
启动项目,访问:http://localhost:40000/user/1
spring-boot
这里直接修改上一篇service-article
服务,用service-article
服务来调用service-user
服务。因此须要修改service-article
,新增User
对象和ArticleController
,在ArticleController
中添加一个查询接口。
这里调用服务都是使用RestTemplate
,因此先在入口内中注册注册RestTemplate
,
@SpringBootApplication @EnableEurekaClient public class ArticleApplication { @Bean public RestTemplate restTemplate(){ return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(ArticleApplication.class, args); } }
User实体,能够直接拷贝user微服务的实体类去掉注解便可,由于这里不是持久化对象。
@Data public class User implements Serializable { private Long id; private String username; private int age; }
ArticleController
@RestController public class ArticleController { @Autowired private RestTemplate restTemplate; @GetMapping("/a/u/{id}") public User getUser(@PathVariable("id") Long id){ return restTemplate.getForObject("http://localhost:40000/user/{1}",User.class,id); } }
启动服务,访问:http://localhost:30000/a/u/2
SpringCloudRibbon是一个基于HTTP和TCP的客户端负载均衡工具。是基于Netfix Ribbon实现的。SpringCloud将其封装,可让咱们轻松的将面向服务的REST模板自动转换成客户端负载均衡的服务调用。
修改article-service
,
添加依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
在注册RestTemplate
方法上添加@LoadBalanced
注解开启客户端负载均衡,而后修改请求的URL,直接使用服务名请求,这里可以直接使用服务名,是由于在SpringCloudRibbon中有一个拦截器,他可以在实际调用的时候自动的选取服务实例,并将实际请求的ip地址替换这里的服务名。详细介绍能够查看DD大佬的书:<<SpringCloud微服务实战>>
@GetMapping("/a/u/{id}") public User getUser(@PathVariable("id") Long id){ return restTemplate.getForObject("http://USER-SERVICE:40000/user/{1}",User.class,id); }
最后为了测试负载均衡,咱们须要开启多个USER-SERVICE服务实例;在USER-SERVICE中添加application-pree1.yml
和application-pree2.yml
,具体配与application.yml同样,只要修改server.port
,这里分别是40001和40002。而后打包服务,分别启动两个服务
java -jar user-0.0.1-SNAPSHOT.jar --spring.profiles.active=pree1 java -jar user-0.0.1-SNAPSHOT.jar --spring.profiles.active=pree2
在注册中心能够看到三个USER-SERVICE服务:
最后启动ARTICLE-SERVICE,并访问接口。刷新几回页面,发现三个服务都会打印数据库语句,这里调用方式为线性轮询
当咱们在SpringBoot项目中添加SpringCloudRibbon之后,SpringBoot会为咱们自动化配置Ribbon,有些时候自动化配置是没法知足须要的。咱们都知道在SpringBoot中咱们可使用两种配置属性的方法:使用java config方式和在配置文件中配置。
建立UserServiceConfig
,该类不能在启动时候被扫描到,因此咱们须要将该类放到SpringBoot入口类的上一层路径下。
@Configuration public class UserServiceConfig { /** *将服务检查策略改成PingUrl * @return */ @Bean public IPing ribbonPing(){ return new PingUrl(); } /** * 将负载均衡的策略改成随机选取服务实例 * @return */ @Bean public IRule ribbonRule(){ return new RandomRule(); } }
而后建立RibbonConfig
,这里@RibbonClients
注解是能够指定多个RibbonClient,而@RibbonClient
注解则是指定那个哪一个服务使用哪一个配置类
@Configuration @RibbonClients({ @RibbonClient(name = "user-service",configuration = UserServiceConfig.class), }) public class RibbonConfig { }
在配置文件中配置时候咱们也能够配置全局的和指定客户端方式配置
ribbon.<key>=<value>
,key客户端配置参数名,value为对应的参数值<client>.ribbon.<key>=<value>
,这里的client为指定的服务名。下面为user-service指定负载均衡策略:USER-SERVICE: ribbon: RulePredicateClasses: com.netflix.loadbalancer.RandomRule
更多关于key的配置信息能够查看com.netflix.client.config.CommonClientConfigKey
。
做为SpringCloud学习笔记,可能有不少地方很差。望指出!!!
源码地址:https://gitee.com/wqh3520/spring-cloud-1-9/tree/master/
原文地址:SpringCloud学习之Ribbon