目录
springcloud
nacos组件
1、搭建nacos服务
2、注册微服务到nacos注册中心
3、实现微服务远程调用
搭建两个projectB,通过projectA远程调用。
restTemplate远程调用
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
@RestController
public class HelloController {
@Autowired
private RestTemplate restTemplate;
@RequestMapping("/getUser")
public User getUser(){
// return restTemplate.getForObject("http://localhost:8081/user/info", User.class);
return restTemplate.getForObject("http://projectB/user/info", User.class);
}
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
<version>3.1.8</version>
</dependency>
默认负载均衡为轮询策略
OpenFeign组件
实现远程服务调用
实现负载均衡
在消费者方:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
<version>3.1.8</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>3.1.9</version>
</dependency>
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients //启用FeignClient支持
public class ProjectAApplication {
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(ProjectAApplication.class, args);
}
}
# 这个配置项的作用是允许 Bean 之间存在循环引用
spring.main.allow-circular-references=true
声明远程调用的接口
目标类,目标方法:
@RestController
@RequestMapping("/user")
public class UserController {
@RequestMapping("/info")
public User info(){
return new User(1,"admin");
}
}
//指定远程调用的服务名
@FeignClient(value = "projectB")
public interface UserFeign {
//声明远程调用的接口
@RequestMapping("/user/info")
public User info();
}
在当前服务中测试,远程调用:
@RequestMapping("/user")
@RestController
public class UserController {
@Autowired
private UserFeign userFeign;
@RequestMapping("/getInfo")
public User getInfo(){
return userFeign.info();
}
}
远程方法调用不同类型参数的测试
1、?key=value
2、对象传参
3、Pathvariable 传参
4、@RequestBody
示例代码:
提供者方:
@RestController
@RequestMapping("/user")
public class UserController {
@RequestMapping("/info")
public User info(){
return new User(1,"admin");
}
//restful风格
@RequestMapping("/info2/{id}/{name}")
public User info2(@PathVariable(value = "id") int id,
@PathVariable(value = "name") String name){
return new User(id,name);
}
//?key=value传参
@RequestMapping("/info3")
public User info3(Integer id,String name){
return new User(id,name);
}
//?key=value传参
@RequestMapping("/info4")
public User info4(User user){
return user;
}
//json格式传递
@RequestMapping("/info5")
public User info5(@RequestBody User user){
return user;
}
}
声明接口:
package com.hl.api;
import com.hl.entity.User;
import feign.QueryMap;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.cloud.openfeign.SpringQueryMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
//指定远程调用的服务名
@FeignClient(value = "projectB")
public interface UserFeign {
//声明远程调用的接口
@RequestMapping("/user/info")
public User info();
//restful风格
@RequestMapping("/user/info2/{id}/{name}")
public User info2(@PathVariable(value = "id") int id,
@PathVariable(value = "name") String name);
//?key=value传参
@RequestMapping("/user/info3")
public User info3(@RequestParam("id") Integer id,
@RequestParam("name") String name);
//?key=value传参
@RequestMapping("/user/info4")
public User info4(@SpringQueryMap User user);
//json格式传递
@RequestMapping("/user/info5")
public User info5(@RequestBody User user);
}
消费者方:
@RequestMapping("/user")
@RestController
public class UserController {
@Autowired
private UserFeign userFeign;
@RequestMapping("/getInfo")
public User getInfo(){
return userFeign.info();
}
@RequestMapping("/restFul/{id}/{name}")
public User restFul(@PathVariable Integer id,@PathVariable String name){
// return userFeign.info2(id,name);
// return userFeign.info3(id,name);
User user = new User(id,name);
return userFeign.info4(user);
}
@RequestMapping("/json")
public User json(@RequestBody User user){
return userFeign.info5(user);
}
}
LoadBalancer组件
负载均衡方式
LoadBalancer默认提供了两种负载均衡策略:
-
RandomLoadBalancer - 随机分配策略
-
(默认) RoundRobinLoadBalancer - 轮询分配策略
Ribbon也是一样操作的。
在springcloud-consumer中
-
编写配置类
@Configuration
public class CustomeLoadBalanceConfiguration {
@Bean
public ReactorLoadBalancer<ServiceInstance> reactorServiceInstanceLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory){
String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
return new RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class),name);
}
}
-
修改配置类
@Configuration
@LoadBalancerClient(value = "loadbalancer-provider",configuration = CustomeLoadBalanceConfiguration.class)
public class RestTemplateConfiguration {
@Bean
@LoadBalanced //使用resttemplate方法时,进行客户端负载均衡操作
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
-
测试
重启springcloud-consumer,进行访问,发现会随机访问8082和8084端口的provider。
Nacos配置中心
配置中心简介
随着微服务架构的发展,企业级项目由无数的服务组成,这时候急需用到集中管理、治理的配置的组件,来统一管理各个服务的开关、配置参数、数据库地址、服务器等等,然而这还不够,还要对这个管理配置的组件有着修改后实时发布、多环境、灰度发布、权限控制、审核等等机制,由此配置中心出现了。
配置中心好处
-
集中管理配置文件
-
不同环境不同配置,动态化的配置更新
-
配置信息改变时,不需要重启即可更新配置信息到服务
配置中心产品
-
SpringCloud Config
-
Apollo
-
Nacos
低版本配置
Nacos支持动态的配置管理,将服务的配置信息分环境、分类别进行管理,并且支持热更新。Nacos同springcloud-config一样,在项目初始化时,要保证先从配置中心配置拉取,拉取配置后,才能保证项目的正常启动。不过与Config不同Nacos的配置信息存储于数据库中,支持配置信息的监听和版本回滚。
springboot中配置文件的加载是存在优先顺序的,bootstrap.yml(properties)优先级高于application.yml(properties)。
bootstrap.yml(bootstrap.properties)(springboot固定名称的配置文件) 用来程序引导时执行,应用于更加早期配置信息读取。
高版本配置
依然使用application.yml ,application.properties
导入nacos配置中心需要动态更新的配置文件。
操作步骤
1、nacos配置中心创建配置文件,添加动态参数
2、微服务上
添加jar包(nacos-config配置中心)
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
配置文件指定相关参数(配置中心地址、用户名、密码,导入配置中心的动态配置文件)
#nacos配置中心
spring.cloud.nacos.config.server-addr=localhost:8848
spring.cloud.nacos.config.username=nacos
spring.cloud.nacos.config.password=nacos
#spring.cloud.nacos.config.context-path=/nacos
# Nacos 配置中心的namespace。需要注意,如果使用 public 的 namcespace ,请不要填写这个值,直接留空即可
#spring.cloud.nacos.config.namespace=
spring.config.import=nacos:projectA.yml?refresh=true
测试:
动态获取配置中心相关参数,修改配置中心,无需重启项目,看参数是否生效。
@Configuration
@RefreshScope
@RestController
public class MyNacosConfig {
@Value("${spring.data.username}")
private String username;
@Value("${spring.data.password}")
private String password;
@RequestMapping("/getLoginUser")
public LoginUser getLoginUser() {
return new LoginUser(username,password);
}
}