Nginx
Nginx由内核和模块组成:
- 内核:仅仅通过查询配置文件与客户端请求URL匹配,启动不同模块完成相应工作
- 模块:启动nginx后,模块自动被加载。每个模块都有可能处理某个请求,但是同个请求只能有一个模块完成
nginx启动后,会有一个Master进程和多个Worker进程。采用异步非阻塞的方式来处理请求。当Nginx上的进程数与CPU核数相同时,进程间切换代价时最小的
Nginx配置负载均衡后,进入网关,网关决定进到哪个真是的web服务器
负载均衡
负载均衡从upstream
模块定义
#动态服务器组
upstream myServer {
server localhost:8080;
server localhost:8081;
server localhost:8082;
server localhost:8083;
}
upstream
模块配置完成之后,在server模块中的location中指定反向代理到服务器列表,location的正则有多种规则
配置网关
#所有的请求都跳转到myServer。
location ~ .*$ {
index index.jsp index.html;
# 例如访问 location/test/1 请求会被转发到 myServer/test/1
proxy_pass http://myServer;
}
负载均衡策略 | 描述 |
轮询 | 默认方式 |
weight | 权重方式 |
ip_hash | 依据ip分配方式 |
least_conn | 最少连接方式 |
fair(第三方) | 响应时间方式 |
url_hash(第三方) | 依据URL分配方式 |
缺省采用的就是轮询策略
weight默认值是1;数值与访问比率成正比
#动态服务器组
upstream myServer {
server localhost:8080 weight=2;
server localhost:8081;
server localhost:8082 backup;
server localhost:8083 max_fails=3 fail_timeout=20s;
}
upstream dynamic_zuoyu {
ip_hash; #保证每个访客固定访问一个后端服务器
server localhost:8080 weight=2;
server localhost:8081;
server localhost:8082;
server localhost:8083 max_fails=3 fail_timeout=20s;
}
负载均衡调度的状态
- dowm:当前的server暂时不参与负载均衡。
- backup:预留的备份服务器。
- max_fails:允许请求失败的次数。
- fail_timeout:经过max_fails失败后,服务器暂停的时间。
- max_conns:限制最大的接收连接数。
zuul
Zuul 的核心是一系列的过滤器。可以扩展很多功能,例如:
- 动态路由:动态的将客户端请求路由到后端不同的不同服务
- 请求监控:记录详细请求响应日志、访问量、监控状态等
- 认证权限:对每一个访问的请求做认证,拒绝非法请求
- 压力测试
- 静态响应
- 负载削减
- 等
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
#hhh是自定义名称,当访问路径是/test/**时,会把请求转发到demo项目中
zuul.routes.hhh.path=/test/**
zuul.routes.hhh.service-id=demo
默认的转发规则就是“API 网关地址+访问的服务名称+接口 URI”
不需要添加上边的配置。但是都要结合eureka使用。不然无法找到服务
也可以直接定义url
zuul.routes.hhh.path=/hhh/**
zuul.routes.hhh.url=http://www.baidu.com #访问/hhh/*** 会跳转到这个网址
ZuulFilter
ZuulFilter的四个方法:
- shouldFilter
是否执行该过滤器,true 为执行,false 为不执行,这个也可以利用配置中心来实现,达到动态的开启和关闭过滤器。 - filterType
过滤器类型,可选值有 pre、route、post、error。 - filterOrder
过滤器的执行顺序,数值越小,优先级越高。 - run
执行自己的业务逻辑。
过滤器的四种类型:
- pre
可以在请求被路由之前调用。适用于身份认证的场景,认证通过后再继续执行下面的流程。 - route
在路由请求时被调用。适用于灰度发布场景,在将要路由的时候可以做一些自定义的逻辑。 - post
在 route 和 error 过滤器之后被调用。这种过滤器将请求路由到达具体的服务之后执行。适用于需要添加响应头,记录响应日志等应用场景。 - error
处理请求时发生错误时被调用。在执行过程中发送错误时会进入 error 过滤器,可以用来统一记录错误信息。
自定义ip过滤器
public class IpFilter extends ZuulFilter {
// IP黑名单列表
private List<String> blackIpList = Arrays.asList("127.0.0.1");
public IpFilter() {
super();
}
@Override
public boolean shouldFilter() {
return true
}
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 1;
}
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
String ip = IpUtils.getIpAddr(ctx.getRequest());
// 在黑名单中禁用
if (StringUtils.isNotBlank(ip) && blackIpList.contains(ip)) {
// false,zuul不会将请求转发到后台服务
ctx.setSendZuulResponse(false);
ResponseData data = ResponseData.fail("非法请求 ", ResponseCode.NO_AUTH_CODE.getCode());
// 返回数据给客户端
ctx.setResponseBody(JsonUtils.toJson(data));
ctx.getResponse().setContentType("application/json; charset=utf-8");
return null;
}
return null;
}
}
启用自定义的ip过滤器
@Configuration
public class FilterConfig {
@Bean
public IpFilter ipFilter() {
return new IpFilter();
}
}