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.使用缓存:

相关推荐
Pluchon6 小时前
硅基计划4.0 算法 简单模拟实现位图&布隆过滤器
java·大数据·开发语言·数据结构·算法·哈希算法
我命由我123456 小时前
Java 泛型 - Java 泛型通配符(上界通配符、下界通配符、无界通配符、PECS 原则)
java·开发语言·后端·java-ee·intellij-idea·idea·intellij idea
Seven976 小时前
AQS深度探索:以ReentrantLock看Java并发编程的高效实现
java
数据知道6 小时前
PostgreSQL 性能优化: I/O 瓶颈分析,以及如何提高数据库的 I/O 性能?
数据库·postgresql·性能优化
4311媒体网6 小时前
C语言操作符全解析 C语言操作符详解
java·c语言·jvm
淡忘_cx6 小时前
使用Jenkins自动化部署spring-java项目+宝塔重启项目命令(2.528.2版本)
java·自动化·jenkins
毕设源码-钟学长6 小时前
【开题答辩全过程】以 基于SSM的孤儿救助信息管理系统设计与实现为例,包含答辩的问题和答案
java
独自破碎E6 小时前
【曼哈顿距离】BISHI25 最大 FST 距离
java·开发语言
苏涵.6 小时前
Java三大集合:List、Set、Map
java·开发语言