Nginx性能优化

一、线程池

通过ThreadPoolExecutor类创建线程池时7个核心参数:

  1. corePoolSize:线程池的核心线程数,即即使线程池中的线程处于空闲状态,这些线程也不会被终止,除非设置了allowCoreThreadTimeOut为true。
  2. maximumPoolSize:线程池允许的最大线程数。当线程池中的线程数达到corePoolSize后,如果继续提交任务,线程池会尝试复用已有的线程执行新任务。如果已有的线程都在执行任务,则会创建新的线程,直到总线程数达到maximumPoolSize。
  3. keepAliveTime:当线程池中的线程数超过corePoolSize时,多余的空闲线程在等待新任务的时间超过keepAliveTime后会被终止。
  4. unit:keepAliveTime参数的时间单位,如秒、分钟等,通常使用TimeUnit枚举值表示。
  5. workQueue:用于保存待处理任务的阻塞队列。常见的阻塞队列实现包括ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue等。
  6. threadFactory:用于设置创建线程的工厂,可以通过自定义线程工厂来设置线程名称、优先级等属性。
  7. handler:拒绝策略,当线程池和队列都满时,如何处理新提交的任务。常见的拒绝策略包括AbortPolicy(抛出异常;默认)、CallerRunsPolicy(由调用线程执行任务)、DiscardPolicy(丢弃任务)和DiscardOldestPolicy(丢弃队列中最老的任务)。

二、nginx

Nginx中有几类配置文件,它们的作用不同:

而我们一般对于Nginx的配置、调优都是在 nginx.conf文件中进行的。

页面静态化实现技术有:velocity、freemarker、Thymeleaf。

2.1 基于IP限流

基于IP限流可以限制特定IP地址在单位时间内的请求频率。这有助于防止单个IP地址对服务器发起过多的请求,导致服务器过载。

配置项:

配置项 说明
limit_req_zone 用于定义限流区域和相关参数。这个区域用于存储客户端IP地址的请求计数信息,并根据定义的速率限制来处理请求。例如,limit_req_zone binaryremoteaddrzone=mylimit:10mrate=1r/s;这里,binary_remote_addr zone=mylimit:10m rate=1r/s; 这里,binaryremoteaddrzone=mylimit:10mrate=1r/s;这里,binary_remote_addr是客户端的IP地址(二进制格式),mylimit是区域名称,10m是分配给该区域的共享内存大小,1r/s表示每秒只允许一个请求。
limit_req 在需要限流的 nginx.conf中的http中的location 中使用,引用之前定义的限流区域。当客户端的请求频率超过指定的限制时,Nginx会采取相应的措施,如延迟请求或拒绝请求。例如,limit_req zone=mylimit burst=5 nodelay; 这里,mylimit是之前定义的限流区域名称,burst=5表示在超过速率限制时,还可以处理额外的5个请求,而nodelay表示立即拒绝超出限制的请求,而不是将它们放入队列中等待处理。

示例:如果限制每个IP地址每秒只能发送一个请求到/api路径的话;可以如下配置:

Nginx 复制代码
http {  
    limit_req_zone $binary_remote_addr zone=mylimit:10m rate=1r/s;  
  
    server {  
        listen 80;  
  
        location /api {  
            limit_req zone=mylimit burst=5 nodelay;  
            # 其他配置...  
        }  
    }  
}

说明:如果某个IP地址在1秒内发送了超过一个请求到/api路径,Nginx将根据burst参数的值来决定如何处理这些额外的请求。上面的示例中,由于设置了burst=5,所以Nginx会允许额外的5个请求,但会立即拒绝超出这个限制的请求(由于nodelay参数的存在)。

2.2 基于连接数限流

连接数限流可以限制单个IP地址或特定key的并发连接数。这有助于防止单个IP地址或客户端建立过多的连接,耗尽服务器资源。

配置项:

配置项 说明
limit_conn_zone 用于定义一个共享内存区域,这个区域用于存储每个客户端的连接数信息。例如,limit_conn_zone binaryremoteaddrzone=addr:10m;这行代码定义了一个名为addr、大小为10MB的共享内存区域,用于根据客户端的IP地址(binary_remote_addr zone=addr:10m; 这行代码定义了一个名为addr、大小为10MB的共享内存区域,用于根据客户端的IP地址(binaryremoteaddrzone=addr:10m;这行代码定义了一个名为addr、大小为10MB的共享内存区域,用于根据客户端的IP地址(binary_remote_addr)来限制连接数。
limit_conn 用于在指定的位置限制客户端的连接数。它引用之前通过limit_conn_zone定义的共享内存区域和key,当连接数达到限制时,新的连接将被拒绝。例如,location / { limit_conn addr 10; } 这行代码表示,对于IP地址为key的连接,最大并发连接数为10。如果某个IP地址的并发连接数超过了这个限制,新的连接请求将被Nginx拒绝。

示例:

Nginx 复制代码
http {  
    limit_conn_zone $binary_remote_addr zone=addr:10m;  
  
    server {  
        listen 80;  
        server_name example.com;  
  
        location / {  
            limit_conn addr 10;  
            # 其他配置...  
        }  
    }  
}

说明:在上述示例中,limit_conn_zone定义了一个名为addr的连接数限流区域,该区域使用IP地址作为key,并设置了10MB的共享内存区域来存储状态信息。在location块中,limit_conn指令引用了连接数限流区域,并设置了10作为单个IP地址的最大并发连接数。如果某个IP地址的并发连接数超过了这个限制,Nginx将拒绝新的连接请求。

2.3 IP限流和连接数限流区别

一个连接中可以发起多个请求。这就是最核心的区别。

  • 关注点不同:IP限流关注的是请求的频率,而连接数限流关注的是同时建立的连接数量。
  • 应用场景不同:IP限流更适用于防止密码暴力破解等场景,因为它关注的是请求的频率;而连接数限流更适用于防止资源耗尽的场景,因为它关注的是连接的数量。
  • 效果不同:IP限流可能会允许某个IP地址在短时间内建立多个连接,但会限制它的请求频率;而连接数限流则会限制某个IP地址同时建立的连接数量,不论请求频率如何。

三、spring cache

3.1 spring cache 简介

Spring Cache是Spring框架提供的一种缓存抽象机制,或者说缓存框架,主要简化应用中的缓存操作。它通过将方法的返回值缓存起来,当下次调用同一方法时,如果传入的参数与之前的调用相同,就可以直接从缓存中获取结果,而不需要再执行方法体中的代码。这种方式可以显著提高系统的性能和响应速度。

Spring Cache的主要特点包括:

  1. 声明式缓存:通过在方法上添加注解,如@Cacheable、@CachePut、@CacheEvict等,来声明缓存的行为,无需手动编写缓存代码。这使得缓存功能更加易于集成和使用。
  2. 多种缓存支持:Spring Cache提供了对多种缓存框架的支持,包括Redis、EhCache、Guava Cache、Caffeine等。这意味着你可以根据项目的需要选择合适的缓存实现。
  3. 基于AOP的缓存:Spring Cache利用了面向切面编程(AOP)的技术,实现了基于注解的缓存功能。这使得业务代码无需关心底层使用了什么缓存框架,只需简单地添加注解即可实现缓存功能,降低了对代码的侵入性。
  4. 动态指定缓存Key和条件:Spring Cache还支持使用SpEL(Spring Expression Language)表达式来动态地指定缓存的Key和条件等。这使得缓存的配置更加灵活和强大。

Spring Cache主要是通过CacheManager接口来统一不同的缓存技术。CacheManager是Spring提供的各种缓存技术抽象接口;Spring Cache 的具体架构如下:

  • CacheInterceptor缓存拦截器是Spring AOP(面向切面编程)中的一个拦截器,实现了MethodInterceptor接口。当一个方法被带有缓存注解(如@Cacheable、@CachePut、@CacheEvict等)标记时,CacheInterceptor会拦截这个方法的调用。拦截后,CacheInterceptor会根据注解的指示,检查缓存、从缓存中获取数据、将数据存入缓存或删除缓存中的数据。
  • CacheAspectSupport缓存切面支持 是CacheInterceptor的基类,提供了缓存操作的核心实现。它封装了缓存操作的逻辑,如计算缓存键、检查缓存、从缓存中获取数据、将数据存入缓存或删除缓存中的数据等。当CacheInterceptor拦截到一个方法调用时,它会委托给CacheAspectSupport来处理实际的缓存操作。
  • CacheManager 缓存管理器 是Spring提供的缓存管理器接口,它维护着多个Cache。不同的缓存技术需要实现不同的Cache接口。当应用程序需要缓存数据时,它会先通过CacheManager获得某个Cache,然后使用该Cache的API进行数据的存取。

3.2 常用注解

在Spring Cache中,常见的缓存注解主要有@EnableCaching 、 @Caching、@Cacheable、@CachePut、@CacheEvict和@CacheConfig。

在不同的业务操作时;一般的缓存操作大概如下:

  • 新增:删除分页、列表的缓存,再将当前这条数据存缓存。
  • 修改:删除分页、列表和当前这条数据的缓存。
  • 删除:删除分页、列表和id对应的那些缓存。
  • 查询:不会修改数据;所以只做存储缓存。将本次查询条件或者分页条件对应的查询结果缓存到缓存中。
    若不在上述的操作中且缓存逻辑不定,可以全部缓存删除,保持数据一致。

3.3 使用spring cache

step1.引入依赖:

xml 复制代码
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!--cache底层的实现不同引入不一样-->
<dependency>
  <groupId>org.redisson</groupId>
  <artifactId>redisson-spring-boot-starter</artifactId>
</dependency>

step2.配置缓存:

step3.使用缓存:

相关推荐
海兰2 分钟前
使用 Spring AI 打造企业级 RAG 知识库第二部分:AI 实战
java·人工智能·spring
历程里程碑19 分钟前
二叉树---二叉树的中序遍历
java·大数据·开发语言·elasticsearch·链表·搜索引擎·lua
小信丶32 分钟前
Spring Cloud Stream EnableBinding注解详解:定义、应用场景与示例代码
java·spring boot·后端·spring
无限进步_36 分钟前
【C++】验证回文字符串:高效算法详解与优化
java·开发语言·c++·git·算法·github·visual studio
亚历克斯神37 分钟前
Spring Cloud 2026 架构演进
java·spring·微服务
七夜zippoe40 分钟前
Spring Cloud与Dubbo架构哲学对决
java·spring cloud·架构·dubbo·配置中心
海派程序猿41 分钟前
Spring Cloud Config拉取配置过慢导致服务启动延迟的优化技巧
java
阿维的博客日记1 小时前
为什么不逃逸代表不需要锁,JIT会直接删掉锁
java
William Dawson1 小时前
CAS的底层实现
java
九英里路1 小时前
cpp容器——string模拟实现
java·前端·数据结构·c++·算法·容器·字符串