接着上篇我们介绍的Spring Cloud Alibaba,下面来继续学习构建云原生应用的动态服务发现、配置管理和服务管理平台——Nacos介绍。
共同学习|Spring Cloud Alibaba一一简介篇-CSDN博客
3、Nacos介绍
Redirecting to: https://nacos.io/
什么是nacos?
Nacos致力于帮助您发现、配置和管理微服务。Nacos提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。
Nacos安装
1、Nacos下载
https://github.com/alibaba/nacos/releases/tag/1.4.2
2、Windows运行Nacos
3、Linux运行Nacos
./startup.sh -m standalone
4.访问NacosWeb页面
http://localhost:8848/nacos
5、登录Nacos
默认的用户名密码 nacos/nacos
4、Nacos服务注册与发现
Nacos可以作为服务注册中心替代Eureka,服务注册中心,它是服务,其实例及元数据的数据库。服务实例在启动时注册到服务注册表,并在关闭时注销。服务和路由器的客户端查询服务注册表以查找服务的可用实例。服务注册中心可能会调用服务实例的健康检查API来验证它是否能够处理请求。
下面演示自定义一个服务注册到Nacos上面
1、pom文件
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.3.RELEASE</version>
<relativePath/><!-- Nacos版本和SpringBoot版本需要匹配
</parent>
<groupId>com.gf</groupId>
<artifactId>springcloud-alibaba-@1-server1</artifactId>
<version>8.8.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 该服务注册到nacos上面,需要导入这个依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
<!-- SpringCloudAlibaba版本-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.8.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
2、yml
server:
port: 8081
spring:
application:
name: server-provider
cloud:
nacos:
discovery:
server-addr: 127.8..1:8848 # 注册到nacos上的地址
management:
endpoints:
web :
exposure:
include: '*' # 暴露该服务的所有端口
3、自定义接口
@RestController
@RequestMapping("/provider")
public class ProviderController [
@Value("${server.port}")
private Integer port;
@RequestMapping("/hello/(id}")
public string hello(@PathVariable Integer id){
return "[” + port +"]provider/hello/” + id;
}
}
4、主启动类
package com.qf.serverprovider ;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client,discovery.EnableDiscoveryClient;
@SpringBootApplication(scanBasePackages = "com.gf")
@EnableDiscoveryClient
public class ServerProviderApplication{
public static void main(string[] args){
SpringApplication.run(ServerproviderApplication.class,args);
}
}
5、注册中心查看
5、Nacos服务发现
客户端负载均衡
Nacos中提高了客户端操作,可以从NacosService中拉去服务信息,
Autowired
private NacosDiscoveryclient nacosDiscoveryClient;
@test
void test() {
// 1.从Nacos获取服务信息列表
List<serviceInstance> serverilist = nacosDiscoveryclient.getinstances("server1");
// 2.随机返回一个实例,客户端负或均衡
Random random = new Random()
ServiceInstance serviceInstance = serverilist.get(random,nextint(serverilist.size())):
String host = serviceinstance.getHost();
System.out.println(host);
}
同一个服务在Nacos注册中心可能会存在多个实例,客户端通过服务名称拉取到的实例就会存在多个,此时可以通过客户端负载均衡选择一个实例进行调用。
客户端负载均衡--ribbon
Nacos底层封装了ribbon,所以在nacos中可以使用ribbon的方式进行服务调用
@Autowired
private RestTemplate restTemplate;
@Bean
@LoadBalanced // 负载均衡
public RestTemplate restTemplate(){
return new RestTemplate();
}
@GetMapping("/server2")
public string server2() (
// 1、从Nacos获取服务信息列表
return restTemplate.getForObject("http://server1/server1"String.class);
}
Ribbon负载均衡策略
RandomRule 随机策略 随机选择server
RoundRobinRule 轮询策略 按照顺序选择server (ribbon默认策略)
RetryRule 重试策略 在一个配置时间段内,当选择server不成功,则一直尝试选择一个可用的server
BestAvailableRule 最低并发策略,逐个考察server,如果server断路器打开,则忽略,在选择其中并发链最低的server
AvailabilityFilteringRule 可用过滤策略 过滤掉一直失败并被标记为circuit tripped的server,过滤掉那些高并发链接的server(active connections 超过配置的阈值)
ResponseTimeWeightedRule 响应时间加权重策略 根据server的响应时间重新分配权重,响应时间越长,权重越低,被选择的概率也就越低。响应时间越短,权重越高,被选中的概率越高,这个策略很贴切,综合了各种因素,比如:网络,磁盘,IO等,都直接影响响应时间
ZoneAvoidanceRule 区域权重策略 综合判断server所在区域的性能,和server的可用性,轮训选择server并且判断一个AWS Zone的运行性能是否可用,剔除不可用的Zone中的所有server
feign调用
1、pom文件
因为feign是SpringCloud中提供的组件,所以最好导入SpringCloud的依赖
<dependencies>
<!-- openfeign依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<!-- SpringCloudAlibaba版本 -->
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- SpringCloud 依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
2、定义feign接口
@FeignClient(value = "provider-1")
public interface HelloService {
@RequestMapping("/hello")
public string hello();
}
3、开启feign包扫描
@EnableDiscoveryClient
@SpringBootApplication(scanBasePackages = "com.qf")
@EnableFeignClients(basePackages = "com.qf.feign")
public class SpringcloudAlibaba01Server1Application {
public static void main(string[] args) {
SpringApplication.run(SpringcloudAlibaba01Server1Application.class, args)
}
}
Feign调用传递参数
注意事项
- 如果你传递的参数,比较复杂时,默认采用POST的请求方式。
- 传递单个参数时,推荐使用@pathVariable,如果传递得单个参数比较多,这里也可以采用@RequestParam,不要省略value属性
- 传递对象参数时,统一采用json的方式,添加@RequestBody
- Client接口必须采用@RequestMapping
feign接口的调用
@FeignClient(value = "PROVIDER")
@RequestMapping(value = "/provider")
public interface IProviderservice f
@RequestMapping(value ="/hel1o")
public string hello();
@RequestMapping(value "/getuserById/{}id}") // 这里必须要写属性名称,它不像springmvc那样会自动的把形参作为参数值
public string getuserByid(@Pathvariable("id") Integer id);
@RequestMapping(value = "/login") // 这里须要写属性名称,它不想springrvc那祥会自动的把形参作为参数值
public String login(@RequestParam("username") String username, @RequestParam("password") String password);
// fein不支持直接传递对象,可以通过这样方式转成son然后传递给服务提供者,服务提供者收到的ison字符申
// feign[对象]--》对象转成json--》provider[对象]
@RequestMapping(value = "/adduserFrom"consumes = "application/json")
public string adduserFrom(RequestBody User user);
@RequestMapping(value = /adduserJsoN")
public string adduserjsoN(aRequestbody User user);
}
Feign日志调用
Feign提供了日志打印功能,我们在项目中可以通过配置来调整日志级别,从而了解Feign中http请求的细节,也就是说feign提供的日志功能可以对接口的调用情况进行监控和输出。
日志级别:
NONE:默认的,不显示任何日志
BASIC:仅记录请求方法,URL、响应状态码以及之行时间
HEADERS:除了BASIC中定义的信息以外,还有请求和响应的头信息
FULL:除了HEADERS中定义的信息之外,还有请求和响应的正文以及元数据
01-USER-V2是服务名称,代表调用该服务日志级别是full,这里还可以换成default代表市全局的配置。
feign:
client:
config:01-USER-V2: # default
loggerLevel: full
logging:
level:
com.ts: debug
Feign超时时间
feign调用服务设置超时时间,超过指定时间未响应就会抛出异常。如果开启了hystrix这样配置是无效的,需要配置Hystrix中的超时时间。
feign:
client:
config:
01-USER-V2:
loggerLevel: full
connectTimeout: 3088
readTimeout: 3088
# 或者这样设置
ribbon:
ReadTimeout: 38 #负载均衡超时时间,默认值5000
ConnectTimeout: 3000 #ribbon请求连接的超时时间,默认值2000
Feign负载均衡--权重
1、在注册中心设置权重
2、自定义负载均衡规则
import com.alibaba.cloud.nacos,NacosDiscoveryProperties;
import com.alibabacloud.nacos.ribbon,Nacosserver;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.netflix.client.config.Iclientconfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.DynamicserverListLoadBalancer;
import com.netflix.loadbalancer.server;
import org.springframework.beans.factory.annotation.Autowired;
public class NacosweightRandomV2Rule extends AbstractLoadBalancerRule{
@Autowired
private NacosDiscoveryProperties discoveryProperties;
@override
public server choose(object key) {
DynamicServerlistLoadBalancer loadBalancer = (DynamicserverlistloadBalancer) getloadBalancer();
String name = loadBalancer .getName();
try{
Instance instance = discoveryProperties.namingserviceInstance().selectoneHealthyInstance(name);
System.out.println("选中的instance = "+instance);
/*
* instance转server的逻辑遂考自:
*org.springframework.cloud.alibaba,nacos.ribbon.NacosServerList.instancesToserverList
*/
return new Nacosserver(instance);
} catch (NacosException e) {
System.out.println("发生异常:"+e);
return null;
}
}
@override
public void initwithNiwsConfig(IClientconfig iclientConfig) {
}
}
3、使用最定义负载均衡规则
@Bean
public IRule rule(){
return new NacosweightRandomV2Rule();
}