概述
nginx [engine x] is an HTTP and reverse proxy server, a mail proxy server, and a generic TCP/UDP proxy server, originally written by Igor Sysoev. For a long time, it has been running on many heavily loaded Russian sites including Yandex, Mail.Ru, VK, and Rambler. According to Netcraft, nginx served or proxied 25.28% busiest sites in October 2018. Here are some of the success stories: Dropbox, Netflix, Wordpress.com, FastMail.FM.
特点是:占用内存少;安装简单、配置文件非常简洁(还能够支持perl语法)、Bug非常少的服务,7*24小时不间断运行,在不间断服务的情况下进行软件版本的升级;nginx代码完全用C语言从头写成,官方数据测试表明能够支持高达50000个并发连接数响应。
nginx日志说明
每启动一个nginx实例,nginx.pid中端口号都会发生变化,该日志文件中显示的会是最新的。
代理
正向代理
代理的是客户端,这样客户端可以绕过一些访问限制,比如vpn。
反向代理
代理的是服务器端,这样服务器端动态扩容可以在无感知的情况下进行。
负载均衡
nginx负载均衡的策略有2种:内置策略和扩展策略。内置策略为轮询、加权轮询、IP hash;扩展策略看开发者个人定义了。
nginx常用命令(Windows下操作)
在nginx安装目录下cmd
窗口执行
启动nginx
nginx.exe
快速停止nginx
nginx -s stop
完整有序的的停止nginx
nginx -s quit
通过cmd指令关闭nginx
taskkill /f /t /im nginx.exe
重新加载nginx
nginx -s reload
查看nginx应用进程端口号的指令
tasklist | findstr "nginx.exe"
nginx常用命令(Linux下操作)
./nginx 启动
./nginx -s stop 停止
./nginx -s quit 安全退出
./nginx -s reload 重新加载配置文件
ps aux | grep nginx 查看nginx进程
实战:Spring Boot结合Nginx演示负载均衡
1、项目架构
2、Spring Boot 工程
说明
在工程目录下新建两个工程,分别为server-9001
和server-9002
,这两个服务除了端口号不一致,提供的服务都是一样的。结构如下
源码
server-9001的pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.tgy</groupId>
<artifactId>server-9001</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>server-9001</name>
<description>server-9001</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
server-9001的application.properties文件
server.port=9001
#server.tomcat.processor-cache=0
#关闭缓存,否则由于默认缓存会访问到不属于本服务的对象信息
spring.cache.type=NONE
server-9002的application.properties文件
server.port=9002
#server.tomcat.processor-cache=0
spring.cache.type=NONE
User.java
package com.tgy.pojo;
public class User {
private Long id;
private String name;
private int age;
public User(Long id,String name, int age) {
this.id=id;
this.name = name;
this.age = age;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
server-9001的UserController.java
package com.tgy.controller;
import com.tgy.pojo.User;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Random;
@RestController
@RequestMapping("user")
public class UserController {
@GetMapping("/{id}")
public User getById(@PathVariable("id") Long id){
User user = new User(id, "server-9001-" + id, new Random().nextInt(100));
return user;
}
}
server-9002的UserController.java
package com.tgy.controller;
import com.tgy.pojo.User;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Random;
@RestController
@RequestMapping("user")
public class UserController {
@GetMapping("/{id}")
public User getById(@PathVariable("id") Long id){
User user = new User(id, "server-9002-" + id, new Random().nextInt(100));
return user;
}
}
3、nginx.conf配置
测试不同的负载均衡策略就用不同的nginx配置即可。
轮询
nginx.conf
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
upstream tgyman{
ip_hash;
server 127.0.0.1:9001 weight=1;
server 127.0.0.1:9002 weight=1;
}
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location /{
proxy_pass http://tgyman;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}
IP hash
nginx.conf
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
upstream tgyman{
ip_hash;
server 127.0.0.1:9001 weight=1;
server 127.0.0.1:9002 weight=1;
}
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location /{
proxy_pass http://tgyman;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}
4、启动
启动nginx,启动server-9001和server-9002服务,访问地址:
http:localhost:80/user/1
windows 下不停刷新浏览器页面(Ctrl+R),nginx配置权重轮询结果如下:
题外话
架构:没有什么是加一层解决不了的,如果有,那就再加一层。