远程调用
向其他服务器请求信息(远程调用)
先在application或者configuration中注册一个Bean方便之后使用(可忽略)
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
使用restTemplate方法发送请求
getForObject/postForObject/…
User user = restTemplate.getForObject("http://localhost:8081/user/"+order.getUserId(), User.class);
上面的url是硬编码写死的,很不方便切换,所以使用Eurake注册中心来管理服务提供者的地址
Eureka相当于一个中介所,所有其他微服务都是它的客户(eureka-client)
1、引入服务端依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
2、使用@EnableEurekaServer自动装配
@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(EurekaApplication.class, args);
}
}
3、配置文件(注册Eureka自己,方便之后的Eureka集群)
server:
port: 10086
spring:
application:
name: eurekaserver # 服务名称
eureka:
client:
service-url: # eureka地址信息
defaultZone: http://127.0.0.1:10086/eureka
1、引入客户端依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2、配置文件添加服务名字和Eureka服务的地址
记得给服务添加名字,不然没办法去找到这个服务
spring:
application:
name: userservice # 服务名称
eureka:
client:
service-url: # eureka 的地址
defaultZone: http://127.0.0.1:10086/eureka
右键复制
在弹出窗口中VM option输入-Dserver.port=11111
来选择一个端口,就会产生一个新的服务
1、给RestTemplate添加负载均衡注解
@Bean
@LoadBalanced // eureka负载均衡
public RestTemplate restTemplate(){
return new RestTemplate();
}
2、使用RestTemplate对象,将地址直接换成服务名称,(有问题可以保留端口号试一下)
// 对比 restTemplate.getForObject("http://localhost:8081/user/"+order.getUserId(), User.class);
User user = restTemplate.getForObject("http://userservice/user/"+order.getUserId(), User.class);
这样就可以从eureka直接通过名字拉取服务,而不是写死服务地址
Ribbon是被Spring Boot Cloud内置的,它可以帮助开发人员更轻松地实现客户端负载均衡。
Eureka和Nacos都使用了Ribbon来做负载均衡操作
其中IRule是一个代表查询规则的接口,它有很多实现类(默认ZoneAvoidanceRule):
调整规则的方法(在消费者处修改):
@Bean
public IRule randomRule(){
return new RandomRule();
}
userservice:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
Ribbon是个懒加载,第一次访问的时候才创建RibbonLoadBalancerClient,第一次请求时间长
饥饿加载会在项目启动时创建,第一次访问快,下面是一个对userservice、orderservice执行饥饿加载的示例
多个服务需要用“- name”
ribbon:
eager-load:
enabled: true # 开启饥饿加载
clients:
- userservice
- orderservice
alibaba提供的注册中心
Nacos是要装在服务器端的,学习的时候就装在本机
Nacos下载,下载压缩包,解压到非中文路径中
控制台cmd在当前目录startup -m standalone
以单节点模式启动(默认是集群模式,会报IO错误)
上面有一个地址是控制台,账号密码默认nacos
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>{project-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
spring:
cloud:
nacos:
server-addr: http://127.0.0.1:8848 # nacos 服务端地址
启动客户端微服务,这个时候在你的nacos控制台服务列表就能看到了
和eureka一样,nacos也要在application上定义一个RestTemplate的Bean并且加上@LoadBalanced,使用时也是直接用服务名代替地址
把服务的多个实例分到多个集群中,每个集群一般不在一个地理位置
形成 服务-集群-实例 多级架构
一般尽可能使用本地集群(快),有故障的时候才使用异地的
在客户端修改application.yml添加配置集群名称即可
spring:
cloud:
nacos:
server-addr: http://127.0.0.1:8848 # nacos 服务端地址
discovery:
cluster-name: ChengDu # 配置集群名称,一般是机房位置
先启动两个实例,再把集群名字改了启动另一个实例,就可以模拟两个集群的情况了
我在这个时候需要重新启动nacos,可能是突然多了一个集群它有点呆,连不上控制台了
Nacos也是用了Spring cloud的Ribbon负载均衡
修改规则就是给Ribbon不同的规则实现类
userservice:
ribbon:
NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 负载均衡规则
Nacos的服务存储和数据存储的最外层都是一个namespace,用来做最外层隔离,不同namespace的不能互相访问
Nacos控制台命名空间选项选择新建
在application.yml中添加配置将服务分到某命名空间
spring:
cloud:
nacos:
discovery:
namespace: 71097ffc-c1e7-471b-8538-879599cbf6eb # 命名空间id
Nacos会把实例分成临时(默认)或非临时,对他们的健康检测不同
服务提供者中添加配置,从而设置为非临时实例
spring:
cloud:
nacos:
discovery:
ephemeral: false # 设置为非临时实例
一个服务的配置文件可能和几十个服务实例有关系,在更新配置后这些服务都需要重启
我们需要对服务的配置统一管理,并且对实例做热更新
在Nacos控制台配置管理新增配置,配置内容里应该是可能有变化的配置,不是所有配置 yml就是yaml
在业务中使用Spring的@Value
注解就可以去读取配置文件中的值
之后在项目启动时会先读取nacos配置文件,再读取本地配置文件application.yml并且将其合并,再创建spring容器加载bean
<!-- nacos配置管理-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
bootstrap.yml
文件,它是个引导文件,这个文件的优先级比nacos.yml和application.yml都要高bootstrap.yml
中,以方便找到服务对应配置# 配置的名字是userservice-dev.yaml
spring:
application:
name: userservice # 服务名称,就是配置名称的前半段
profiles:
active: dev # 开发环境,这里是dev,配置名称的后半段
cloud:
nacos:
config:
server-addr: localhost:8848 # nacos地址
file-extension: yaml # 文件后缀名
如果出问题试一下加上bootstrap的依赖,新版springboot不默认启动它
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-bootstrap -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
<version>4.0.4</version>
</dependency>
还要注意nacos控制台中配置文件和服务需要在一个namespace中!!!
@Value获取不到配置的问题查看这个博主
Nacos中的配置文件变更后微服务无需重启即可感知,有两种方法:
方法一:在@Value注入的变量所在类上添加注解@RefreshScope
@RestController
@RequestMapping("/user")
@RefreshScope
public class UserController {
@Value("${pattern.dateformat}") // 尝试通过名字获取nacos配置文件中的值
private String dateformat;
}
方法二:使用@ConfigurationProperties
新建一个类,要保证:
@Data
@Component
@ConfigurationProperties(prefix = "pattern")
public class PatternProperties {
private String dateformat;
}
//对比配置文件的内容
pattern:
dateformat: yyyy-MM-dd HH:mm:ss
服务名-profile.yaml>服务名.yaml>本地配置文件
这篇博文