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:

  • usenginx-lua-moduleModule to writeluaScript that calls the registryHttp APITo get the instance list configurationupstream, timingreloadHot update
  • useJAVA/GolangWrite a separateagent, directly use the SDK corresponding to nacOS language to obtain the instance list generationupstreamAnd useNaocs SDKMonitoring 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.

  1. Downloading binary packages

Click here to download: Latest stable version

  1. 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

  1. Start, ready to use

sh bin/startup.shCopy the code

The core code

  • To obtainconfig.tomlMultiple configurations are supportedupstreamCall 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 togetherupstream
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