background
Let’s recall how nginx configures multiple instances of load balancing as follows:
Upstream serverList {server 172.17.0.111:9999; Server 172.17.0.110:9999; } server { location / { proxy_pass http://serverList; }}Copy the code
When our service instance changes, we need to manually modify nginx.conf and then nginx -s reload.
Under the microservices architecture, our services are registered with registries such as nacOS/Eureka. The registries already maintain IP:PORT lists for all service instances. Why not just use Nginx to get the IP in the registry: The PORT list automatically configures upstream and hot updates. The above ideas are as follows:
- use
nginx-lua-module
Module to writelua
Script that calls the registryHttp API
To get the instance list configurationupstream
, timingreload
Hot update - use
JAVA/Golang
Write a separateagent
, directly use the SDK corresponding to nacOS language to obtain the instance list generationupstream
And useNaocs SDK
Monitoring service changesreload
Nacos nginx – use the template
Nacos-nginx-template The second implementation of the above idea is to let Nginx implement service discovery to NacOS in the form of agents.
-
Downloading binary packages
Click here to download: Latest stable version
-
Configure config. Toml
The configuration file is configured using TOML
Nginx_cmd = "/usr/sbin/nginx" # nacos_ADDR = "172.16.0.100/8848" #nacos reload_interval = 1000 # refresh interval [discover_config1] nginx_config = "/etc/nginx/nginx.conf [discover_config2] nginx_config = "/etc/nginx.conf" nginx_upstream = "/etc/nginx.conf "upsteam2" nacos_service_name = "service2"Copy the code
-
Start, ready to use
sh bin/startup.shCopy the code
The core code
- To obtain
config.toml
Multiple configurations are supportedupstream
Call the Nacos Api to pull the instance list
for (DiscoverConfigBO configBO : list) { namingService.subscribe(configBO.getServiceName(), event -> { List<Instance> instances = namingService .getAllInstances(configBO.getServiceName()); (configbo.getupstream (), configbo.getConfigPath ())); }); }Copy the code
- From the list of instances, piece together
upstream
private boolean refreshUpstream(List<Instance> instances, String nginxUpstream, Pattern = pattern.compile (upstream_reg. replace(PLACEHOLDER, PLACEHOLDER, PLACEHOLDER); nginxUpstream)); String conf = fileutl. readStr(nginxConfigPath); Upstream = upstream_fomat. replace(PLACEHOLDER, nginxUpstream); StringBuffer servers = new StringBuffer(); If (instances. Size () > 0) {for (Instance Instance: instances) {// Unhealthy or unavailable skip if (! instance.isHealthy() || ! instance.isEnabled()) { continue; } servers.append(formatSymbol + " server " + instance.getIp() + ":" + instance.getPort() + "; \n"); } } servers.append(formatSymbol); newUpstream = newUpstream.replace(PLACEHOLDER_SERVER, servers.toString()); Upstream conf = matcher.replaceall (newUpstream); return true; }Copy the code
- Java calls nginx reload
Runtime.getRuntime().exec("nginx -s reload");Copy the code