Table of contents
Nacos
Download Nacos and run
First download the corresponding release package, mainly select the packaged and compiled nacos-server file!
https://github.com/alibaba/nacos/releases/tag/1.4.1
Unzip it to any folder that does not contain a Chinese path.
Enter bin, open the command line in this folder, and enter startup.cmd -m standalone
to start the nacos server.
The default server port is 8848. The above instructions standalone
are expressed in single body, non-cluster mode.
After waiting for the command line to run for a while, enter the URL given by nacos:http://192.168.113.1:8848/nacos/index.html
It can be seen that this is a management interface. The user name and password are both by default. nacos
Just log in.
Configure Nacos
Since our current project setup is a parent-child type, we first need to import the alibaba tool library in the parent project pom.
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.5.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Then import nacos-discovery dependencies in their respective servers
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
Very simple, right?
Finally, you only need to set the address of the nacos server in the configuration file. Unlike
eureka, the registration center here is actually the nacos server we just ran, so there is no need to create an additional project to run the server.
Configuration file writing application.yaml
:
spring:
cloud:
nacos:
server-addr: localhost:8848
Rebuild the corresponding module
Go back to the nacos control panel and you can see the server we generated!
Nacos cluster
Individual instances are grouped together to form a cluster
Clusters are often used for disaster recovery mechanisms
Instances in the same cluster will first access other local instances in the current cluster. If there is no other way, they will go to instances in other clusters.
Setting up a cluster for an instance is very simple. You only need to add the following code to the configuration file to classify it into a cluster.
spring:
cloud:
nacos:
server-addr: localhost:8848
# 设置集群名称,将这个实例归为集群SH管理
discovery:
cluster-name: SH
Nacos load balancing
Suppose there is a situation like this now:
- The service provider has 3 instances, two clusters (BJ, NJ)
- The service consumer has only one instance and one cluster (BJ)
It can be seen that the consumer's cluster is consistent with a cluster in the provider, so according to common sense, we hope that the consumer will directly get data from the provider under the same cluster.
However, since nacos uses polling to achieve load balancing by default, the default configuration must be modified to achieve the final effect.
Option 1: Configure the ribbon in applcation.yaml and specify the load balancing method.
service-consumer:
ribbon:
NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule
Option 2: Use injection to configure in the entry class
@Bean
NacosRule nacosRule() {
return new NacosRule();
}
Load balancing weight value setting
- When the instance weight is 0, it will never be accessed
- Weight value range 0-1
- Among multiple instances in the same cluster, the one with higher weight will be accessed more frequently.
Nacos environment isolation
nacos provides environment isolation options.
From outside to inside, the environment from large to small is as follows:命名空间->分组->服务->实例
Let's first go to the "Namespace" module of the nacos control panel to add a dev
namespace named arbitrarily, and copy the automatically generated ID.
Find the configuration file of any server and use the namespace field to classify the server into a certain namespace
spring:
cloud:
nacos:
server-addr: localhost:8848
discovery:
cluster-name: BJ
# 设置改服务器所处的命名空间
# 这里需要填入我们之前记下来的命名空间ID
namespace: 1688ddc5-4f48-4bdc-bb5b-8c5363edf242
After configuration is completed, restart the server
Enter the nacos console 服务管理->服务列表
and click the navigation bar above to switch namespaces.
In the picture below, we have switched to the newly created dev namespace. It can be seen that the user-server we configured has been governed by this namespace.
Nacos registration details
Server providers can choose between two states when registering with the registry
- Temporary instance status
- Non-temporary instance status
Temporary instances need to actively send regular heartbeat packets to the registration center to prove that they are alive, otherwise they will be removed from the registration center after timeout.
Non-temporary instances do not need to actively send packages, but the registration center confirms whether they are alive. They will be kept forever and will not be deleted due to timeout or other circumstances.
The nacos cluster uses AP mode by default, and switches to CP mode when there are non-temporary instances.
Use the field in the configuration file ephemeral
to mark whether the server is a temporary instance.
spring:
cloud:
nacos:
server-addr: localhost:8848
discovery:
cluster-name: BJ
namespace: 1688ddc5-4f48-4bdc-bb5b-8c5363edf242
# 设置是否为临时实例
ephemeral: false
Nacos more configuration items
Get started quickly
nacos provides a cloud setting configuration file. We only need to create a new configuration file in nacos and write the configuration items that need to be hot updated, and then call the configuration in bootstrap.yaml of the springboot application.
Create a new configuration file. The writing format of the configuration file ID is: <服务器名>-<类型>.yaml
The current configuration file supports yaml and properties formats.
The "server name" here must be exactly the same as the name defined in the application in springboot before this configuration item can be enabled.
Add nacos-config dependency to user-server to enable dependencies
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
After adding nacos-config, create a new configuration file in the resource folder bootstrap.yaml
. At this time, when springboot starts, the configuration file will be read first and then read.application.yaml
spring:
# 服务器名称
application:
name: userservice
# 服务器类型(我们之前定义为dev,这里必须写dev)
profiles:
active: dev
# 其他关键性配置
cloud:
nacos:
server-addr: localhost:8848
config:
# 设置bootstrap配置文件的后缀名
file-extension: yaml
discovery:
cluster-name: BJ
namespace: 1688ddc5-4f48-4bdc-bb5b-8c5363edf242
ephemeral: false
Then come to UserController.java
pull configuration file information
@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {
@Value("${pattern.dataformat}")
private String dataFormat;
@GetMapping("/now")
public String now() {
// 由于我们之前在nacos中设置的配置项配置了pattern属性,这里就可以直接调用对应的属性完成时间格式化了
return LocalDateTime.now().format(DateTimeFormatter.ofPattern(dataFormat));
}
}
Automatic updates
application.yaml
The advantage of using the configuration file directly in nacos is that hot updates can be implemented in real time, instead of having to restart after setting it in the project.
We only need to add annotations to the beans using the nacos configuration file @RefreshScope
.
@Slf4j
@RestController
@RequestMapping("/user")
@RefreshScope // 添加检测配置文件更新的注解
public class UserController {
}
Or you can create a custom configuration class and dynamically obtain the specified configuration
@Component
@Data
@ConfigurationProperties(prefix = "pattern")
public class PatternProperties {
private String dataFormat;
}
We can specifically configure the configuration file that specifies the operating environment (such as dev): userservice-dev.yaml
or define the server's global (common to all environments) configuration file:userservice.yaml
Priority between configuration files: Configuration file with environment parameters > Global configuration file > application.yaml
Feign
Replaces RestTemplate
Compared with resttemplate's inefficient string splicing, feign provides a form of interface operation, allowing us to connect to the corresponding server provider more intuitively.
First introduce dependencies
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
Be sure to remember to enable the feign client in the entry class
@MapperScan("cn.itcast.order.mapper")
@SpringBootApplication
@EnableFeignClients // 开启feign客户端
public class OrderApplication {
}
Create an interface class to obtain the interface of the server provider
Code listing:clients/UserClient.java
// 注解内填入需要链接到的服务器名称
@FeignClient("userservice")
public interface UserClient {
// 表示使用GET请求获取数据
@GetMapping("/user/{id}")
// 同理PathVariable用来填补上方路径中的id占位符
User findById(@PathVariable("id") Long id);
}
Finally rewrite the query logic in the service
@Service
public class OrderService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private UserClient userClient;
public Order queryOrderById(Long orderId) {
// 查询订单
Order order = orderMapper.findById(orderId);
// feign客户端请求user数据库中内容
User user = userClient.findById(order.getUserId());
order.setUser(user);
return order;
}
}
After running orderservice, enter in the browser
http://localhost:10087/order/101
to obtain the corresponding data! In fact, the effect you see is almost the same as resttemplate
Feign custom configuration
Configure log output level
Global configuration
feign:
client:
config:
default:
loggerLevel: FULL
Local configuration (explicitly indicate the server name)
feign:
client:
config:
userservice:
loggerLevel: FULL
Or you can write it in code
Performance optimization
Using the URLConnection connection pool to replace the original single link can improve the efficiency of the feign client.
Import feign-httpclient coordinates
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
Then configure the properties in the configuration file
feign:
client:
config:
default:
# 日志级别最好使用BASIC或者NONE,其他的级别比较耗费性能而且基本用不上
loggerLevel: BASIC
httpclient:
enabled: true
max-connections: 200
max-connections-per-route: 50