openresty (nginx)快速开始

news2024/11/17 17:44:51

文章目录

    • 一、什么是openresty?
    • 二、openresty编译安装
      • 1. 编译安装命令
        • 1.1 编译完成后路径
        • 1.2 常用编译选项解释
      • 2. nginx配置文件配置
        • 2.1 nginx.conf模板
      • 3. nginx常见配置
        • 一个站点配置多个域名
        • nginx配置中location匹配规则
    • 三、OpenResty工作原理
      • OpenResty工作原理
      • OpenResty处理请求流程
      • Nginx架构 的 好处
      • ngx_lua
      • 协程
      • NIO编程(同步阻塞与同步非阻塞详解)
    • 四、工作遇坑细节总结
      • inlude相对路径、lua相对路径问题
      • access_log 和 error_log有什么区别

一、什么是openresty?

官网: https://openresty.org/cn/

OpenResty® 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其**内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。**用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。

总结:openresty 内部已经帮你集成了许多依赖项,编译时只需要–with-xxx 激活这些依赖模块。

二、openresty编译安装

官网参考: https://openresty.org/cn/installation.html

安装路径 选择 /usr/local/openresty,如果不配置安装路径,默认安装路径即 /usr/local/openresty
因为公司准生产 使用的是 1.9.15.1

单纯编译openresty比较简单,openresty强大在很多第三方拓展模块,你需要提前下载好这些模块源码,在配置 openresty编译选项时,把这些模块加进来。当然openrest以及集成大量模块,直接可以使用–with-xxx编译加入这些模块。

1. 编译安装命令

相关命令如下:

tar -zxvf openresty-1.13.6.2.tar.gz

## --with-http_ssl_module依赖openssl
yum install openssl openssl-devel

export INSTALL_DIR=/usr/local/openresty

./configure --prefix=${INSTALL_DIR} --sbin-path=${INSTALL_DIR}/nginx/sbin/nginx --conf-path=${INSTALL_DIR}/nginx/conf/nginx.conf --pid-path=${INSTALL_DIR}/nginx/logs/nginx.pid --lock-path=${INSTALL_DIR}/nginx/logs/nginx.lock --user=root --group=root --with-luajit --without-http_redis2_module --with-http_iconv_module --with-stream --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_auth_request_module --with-pcre --with-pcre-jit --with-debug --with-http_v2_module


gmake
gmake install
1.1 编译完成后路径

安装完成后,nginx命令路径为
/usr/local/openresty/nginx/sbin/nginx
配置文件路径
/usr/local/openresty/nginx/conf/nginx.conf
/usr/local/openresty/nginx/conf/http_vhost/.conf
/usr/local/openresty/nginx/conf/http_upstream/
.conf

# nginx重载
/usr/local/openresty/nginx/sbin/nginx -s reload
1.2 常用编译选项解释
  • –with-stream
    ngx_stream_core_module模块自1.9.0版开始提供。默认情况下不构建此模块,应使用–with-stream 配置参数启用它。用来实现四层协议的转发、代理或者负载均衡等。stream 模块用于一般的 TCP 代理和负载均衡。

  • –with-http_ssl_module
    Nginx虚拟主机、Nginx模块的安装使用(加密模块–with-http_ssl_module)
    参考URL: https://blog.csdn.net/weixin_41619143/article/details/88429027

    报错: SSL moudules require the OpenSSL library
    解决,执行

    yum -y install openssl openssl-devel
    
  • –with-http_realip_module
    这个模块主要功能就是 在nginx访问日志中去除代理IP,显示客户的真实IP。作用呢,一般就是统计客户地域或写个统计脚本看有没有流量攻击。

然后nginx.conf中
在这里加上"http_x_forwarded_for"’ 段,获取真实IP用的 log_format main ’

HTTP模块,不要在server中用,要在HTTP区用。这样就是全局使用。

  • –with-http_v2_module
    支持http2协议。

2. nginx配置文件配置

## 复制配置好的nginx.conf到conf目录 ${INSTALL_DIR}为你前面定义的安装目录
cp -rf nginx.conf ${INSTALL_DIR}/nginx/conf/
# 修改nginx.conf中的工作线程数为CPU核数
CPU_NUM=`cat /proc/cpuinfo | grep processor|wc -l | awk -F' ' '{print $NF}' | sed -n '$p'`
sed -i "s/^worker_processes.*/worker_processes ${CPU_NUM};/g" ${INSTALL_DIR}/nginx/conf/nginx.conf

创建nginx日志目录(你的nginx.conf中配置的,这里创建好目录)

# create nginx logs dirtory
mkdir -p /home/logs/nginx
2.1 nginx.conf模板
# nginx的工作进程运行时的身份,也就是进程文件的属主和属组属性,如果在源码安装时configure配置已经指定用户和组,这里可以注释掉
#user  root;
# 定义nginx的工作进程的数量,一般为CPU核数或核数的倍数,该参数与并发量有关
worker_processes 4;
#worker_cpu_affinity 0001 0010 0100 1000;

# 错误日志的位置
error_log  /home/logs/nginx/error.log  error;
# nginx的master进程的pid存储文件
pid        /usr/local/openresty/nginx/logs/nginx.pid;

worker_rlimit_nofile 307200;

events {
    use epoll;
     # 每一个工作进程可以接收的请求连接数,一般与系统的进程可以打开的文件描述符数量相同,
    worker_connections 51200;
}

#流模块
stream {
    include tcp_vhost/*.conf;
    include tcp_upstream/*.conf;
}
http {
    # mime.types文件含有nginx支持的媒体类型,include可以加载该文件
    include    mime.types;
    include    fastcgi.conf;
    
    # 访问日志的格式,可以自定义
    log_format main     '$remote_addr $host $remote_user [$time_local] "$request" '
                        '$status $body_bytes_sent "$http_referer" '
                        '"$http_user_agent" "$http_x_forwarded_for" "$upstream_response_time" "$upstream_addr" "$upstream_status" "$request_time"';

     # 指定访问日志的位置和格式main
    access_log off;
    client_header_buffer_size 64k; 
    large_client_header_buffers 8 64k;
    client_max_body_size 500m;
 
    proxy_next_upstream error timeout invalid_header http_502 http_504;

    # 调用系统的方法传输文件,速度更快,
    sendfile     on;
    tcp_nopush   on;
    
    keepalive_requests 10000;
    keepalive_timeout 10;
    ssl_ciphers ECDHE-RSA-AES256-SHA384:AES256-SHA256:RC4:HIGH:!MD5:!aNULL:!eNULL:!NULL:!DH:!EDH:!AESGCM;
     # 隐藏nginx版本号,不再浏览显示
    server_tokens off;
    
    include http_vhost/*.conf;
    include http_upstream/*.conf;

    lua_package_path 'lua/?.lua;../lua/?.lua;/usr/local/openresty/nginx/conf/lua/?.lua;/usr/local/openresty/lualib/?.lua;;';
}

注意: 配置文件中的相对路径,是当前nginx.conf同级目录,注意理解。

比如

include http_vhost/*.conf;
include http_upstream/*.conf;

对应路径为
/usr/local/openresty/nginx/conf/http_vhost
/usr/local/openresty/nginx/conf/http_upstream

3. nginx常见配置

Nginx常用配置有这一篇就够了
参考URL: https://baijiahao.baidu.com/s?id=1642243866657041522&wfr=spider&for=pc

一个站点配置多个域名
server {

listen 80;

server_name aaa.cn bbb.cn;

}

server_name 后跟多个域名即可,多个域名之间用空格分隔

nginx配置中location匹配规则

nginx配置中location匹配规则详解
参考URL: https://www.cnblogs.com/daiyacheng1991/archive/2019/09/04/11459133.html

nginx官方文档给出location语法如下:

location [=|~|~*|^~] uri { … }

其中,方括号中的四种标识符是可选项,用来改变请求字符串和uri的匹配方式。uri是待匹配的请求字符串,可以是不包含正则的字符串,这种模式被称为**“标准的uri";也可以包含正则,这种模式被称为"正则uri"**。

  • location = /uri
    = 开头表示精确匹配。

  • location ^~ /uri
    ^~ 开头对URL路径进行前缀匹配,并且在正则之前

  • location ~ 正则表达式
    ~开头表示区分大小写的正则匹配

  • location ~*正则表达式
    ~*开头表示不区分大小写的正则匹配

  • location /uri
    不带任何修饰符,也表示前缀匹配,但是在正则匹配之后

  • location /
    通用匹配,任何未匹配到其它location的请求都会匹配到,相当于switch中的default

如果匹配规则以^开头,就是匹配以指定字符串开头的路径,如果没有就是匹配url中的内容是否包含指定字符串
如果匹配规则以$结尾,就是匹配以指定字符串结尾的路径

多个location配置的情况下匹配顺序为(当有匹配成功时候,停止匹配,按当前匹配规则处理请求):

优先匹配 =
其次匹配 ^~
按照文件中的匹配顺序执行
最后匹配 /
普通匹配(最长字符匹配)

总结为: (location =) > (location 完整路径) > (location ^~ 路径) > (location ,* 正则顺序) > (location 部分起始路径) > (/)

三、OpenResty工作原理

OpenResty工作原理

Nginx采用的是master-worker模型,也就是一个master进程管理多个worker进程,基本的事件处理都放在worker进程中,master进程负责全局初始化以及对worker进行的管理。

OpenResty中,每个worker进程使用一个LuaVM,当请求被分配到worker时,将在这个LuaVM中创建一个coroutine协程,协程之间数据隔离,每个协程都具有独立的全局变量。

在这里插入图片描述
Nginx设计为主进程和多个工作进程的工作模式,每个进程是单线程来处理多个连接,每个工作进程采用了非阻塞I/O来处理多个连接,从而减少线程上下文切换,从而实现高性能、高并发。因此,生产环境中会通过将CPU绑定给Nginx工作进程,从而提升性能。

OpenResty处理请求流程

Nginx会把一个请求分成不同阶段,第三方模块可以根据自己的行为,挂在到不同阶段中以达到自身目的。OpenResty采用了同样的特性,不同阶段有着不同的处理行为。

Nginx架构 的 好处

Nginx采用多进程模式,对于每个worker进程都是独立的,因此不需要加锁,所以节省了锁带来的性能开销。采用独立的进程的好处在于worker进程之间相互不会影响,当一个进程退出后,其他进程依然工作,以保证服务不会终端。

Nginx采用异步非堵塞的方式去处理请求,异步非堵塞就是当一个线程调用出现阻塞而等待时,其他线程可以去处理其他任务。

ngx_lua

ngx_lua是将Lua嵌入Nginx,让Nginx执行Lua脚本,并且高并发、非阻塞的处理各种请求。Lua内建协程,可以很好的将异步回调转换成顺序调用的形式。ngx_lua在Lua中进行的IO操作都会委托给Nginx的事件模型,从而实现非阻塞调用。开发者可以采用串行的方式编写程序,ngx_lua会自动的在进行阻塞的IO操作中终端,保存上下文,然后将IO操作委托给Nginx事件处理机制,在IO操作完成后,ngx_lua会恢复上下文,程序继续执行,这些操作都是对用户程序透明的。

每个Nginx的worker进程持有一个Lua解释器或LuaJIT实例,这个worker处理的所有请求共享这个实例每个请求的context上下文会被Lua轻量级的协程分隔,从而保证各个请求时独立的。

ngx_lua模块的原理

  • 每个工作进程worker创建一个Lua虚拟机(LuaVM),工作进程worker内部协议共享VM。
  • -每个Nginx I/O原语封装后注入Lua虚拟机,并允许Lua代码直接访问。
  • 每个外部请求都由一个Lua协程处理,协程之间数据隔离。
  • Lua代码调用I/O操作等异步时,会挂起当前协程,而不阻塞工作机进程。
  • I/O等异步操作完成时,还原相关协程相关协议的上下文,并继续运行。

协程

协程,又称微线程,纤程。英文名Coroutine。

协程的概念很早就提出来了,但直到最近几年才在某些语言(如Lua)中得到广泛应用。

子程序,或者称为函数,在所有语言中都是层级调用,比如A调用B,B在执行过程中又调用了C,C执行完毕返回,B执行完毕返回,最后是A执行完毕。

所以子程序调用是通过栈实现的,一个线程就是执行一个子程序。

子程序调用总是一个入口,一次返回,调用顺序是明确的。而协程的调用和子程序不同。

协程看上去也是子程序,但执行过程中,在子程序内部可中断,然后转而执行别的子程序,在适当的时候再返回来接着执行。

注意,在一个子程序中中断,去执行其他子程序,不是函数调用,有点类似CPU的中断。

Java语言里面解决并发问题靠的就是多线程,但线程是个重量级对象,不能频繁创建和销毁,且线程切换成本也很高,为了解决这个问题,java采用了线程池。Java没有官方的协程支持,不过有一些库可以支持,如:Quasar。而一些其他语言本身就支持协程,如:go就内置支持协程。

所谓的协程,可以理解为是一种轻量级的线程,它与线程的主要区别在于

a. 线程切换的过程是由系统内核完成,切换的过程中会进入到内核态。而协程则完全工作在用户态。

b. 线程是否发生切换是由操作系统决定的(抢占式调度),工作线程本身没有决定权。而协程的切换是需要工作协程主动放弃CPU,这样调度器才能让另外一个协程继续运行。

NIO编程(同步阻塞与同步非阻塞详解)

NIO编程(同步阻塞与同步非阻塞详解)
参考URL: https://blog.csdn.net/yswKnight/article/details/79347833

  • BIO与NIO
    IO为同步阻塞形式,NIO为同步非阻塞形式,NIO并没有实现异步,在JDK1.7后升级NIO库包,支持异步非阻塞模型NIO2.0(AIO)

  • BIO(同步阻塞式IO)
    同步阻塞式IO,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。

  • NIO(同步非阻塞式IO)
    同步非阻塞式IO,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理

  • AIO(异步非阻塞式IO)
    异步非阻塞式IO,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理。

  1. 什么是阻塞?
    应用程序在获取网络数据的时候,如果网络传输数据很慢,就会**一直等待,**直到传输完毕为止。

  2. 什么是非阻塞?
    应用程序直接可以获取已经准备就绪好的数据,无需等待。

同步时,应用程序会直接参与IO读写操作,并且我们的应用程序会直接阻塞到某一个方法上,直到数据准备就绪;或者采用轮训的策略实时检查数据的就绪状态,如果就绪则获取数据.

异步时,则所有的IO读写操作交给操作系统,与我们的应用程序没有直接关系,我们程序不需要关系IO读写,当操作系统完成了IO读写操作时,会给我们应用程序发送通知,我们的应用程序直接拿走数据极即可。

四、工作遇坑细节总结

inlude相对路径、lua相对路径问题

比如nginx启动如下:

/home/she/openresty/nginx/sbin/nginx -c /home/she/openresty/nginx/conf/nginx.conf

如下则配置中的include 指的就是当前配置nginx.conf所在的路径,即
/home/she/openresty/nginx/conf/http_vhost/*.conf

        include http_vhost/*.conf;
        include http_upstream/*.conf;

假如其中一个conf有配置如下: 那么这里的conf/lua/access_check.lua 是哪个路径呢?从刚才的经验来看,配置中写的相对路径都是相关该配置当前的路径

        location ~* /api/auth/([-_a-zA-Z0-9/]+) {
            access_by_lua_file conf/lua/access_check.lua;
        }

工作中,竟然发现 /home/she/openresty/nginx/conf/lua/access_check.lua 修改打印一直打不出来?

猜测思考:openresty找lua脚本位置,应该有一个配置查找路径有优先级。
经过百度,果然有配置项,lua_package_path可以配置openresty的文件寻址路径

        lua_package_path 'lua/?.lua;../lua/?.lua;/opt/openresty/nginx/conf/lua/?.lua;/opt/openresty/nginx/conf/lua/dialer/?.lua;;';

经过测试,配置生效。

access_log 和 error_log有什么区别

日志-nginx的access_log与error_log
参考URL: https://blog.csdn.net/ty_hf/article/details/55518070

  • access_log 访问日志
    access_log为访问日志,记录所有对apache服务器进行请求的访问,它的位置和内容由CustomLog指令控制,LogFormat指令可以用来简化该日志的内容和格式。
  • error_log 错误日志
    error_log为错误日志,记录下任何错误的处理请求,它的位置和内容由ErrorLog指令控制,通常服务器出现什么错误,首先对它进行查阅**,是一个最重要的日志文件**。

总结:
error_log 我们可以配置日志等级,我们的lua中的ngx.log打印日志就是根据日志级别打印到该配置项配置的文件路径中。
每个service配置项中,都可以配置自己的 access_log和error_log。从而每个服务看自己的access_log和error_log。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1443507.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[经验] 喉咙沙哑的原因及应对方法是什么 #学习方法#其他#媒体

喉咙沙哑的原因及应对方法是什么 生活中,喉咙不舒服是很常见的情况,尤其是喉咙沙哑,让人感到特别难受,影响睡眠和生活质量。那么喉咙沙哑怎么办呢?接下来我会分享一些简单易行的方法,帮助你缓解这种不适感…

kali最新最简单安装

之前都是用iso镜像文件的 今年好多东西都删库了,所有还是要主要资源的保存 去官网找下载 一般来说都是用虚拟机的 下载完会是一个压缩文件, 解压,然后操作之前需要先下载虚拟机 打开方式用虚拟机打开 kali就按装好了

最简单的基于 FFmpeg 的音频编码器(PCM 编码为 AAC)

最简单的基于 FFmpeg 的音频编码器(PCM 编码为 AAC) 最简单的基于 FFmpeg 的音频编码器(PCM 编码为 AAC)正文结果工程文件下载其他参考链接 最简单的基于 FFmpeg 的音频编码器(PCM 编码为 AAC) 参考雷霄骅…

网络原理(一)

💕"Echo"💕 作者:Mylvzi 文章主要内容:网络原理(一) 一. 应用层 应用层是和程序员联系最密切的一层,对于应用层来说,程序员可以自定义应用层协议,应用层的协议一般要约定好以下两部分内容: 根据需求,明确要传输哪些信…

使用REQUESTDISPATCHER对象调用错误页面

使用REQUESTDISPATCHER对象调用错误页面 问题陈述 InfoSuper公司已经创建了一个动态网站。发生错误时,浏览器中显示的堆栈跟踪很难理解。公司的系统分析师David Wong让公司的软件程序员Don Allen创建自定义错误页面。servlet引发异常时,应使用RequestDisapatcher对象向自定义…

[VulnHub靶机渗透] Misdirection: 1

🍬 博主介绍👨‍🎓 博主介绍:大家好,我是 hacker-routing ,很高兴认识大家~ ✨主攻领域:【渗透领域】【应急响应】 【python】 【VulnHub靶场复现】【面试分析】 🎉点赞➕评论➕收藏…

jmeter-问题二:JMeter进行文件上传时,常用的几种MIME类型

以下是一些常用的MIME类型及其对应的文件扩展名: 文本类型: text/plain: 通常用于纯文本文件,如 .txt 文件。 text/html: 用于HTML文档,即 .html 文件。 application/msword: Microsoft Word文档,即 .doc 和 .docx 文件。 图像…

在Ubuntu22.04上部署ComfyUI

ComfyUI 是 一个基于节点流程的 Stable Diffusion 操作界面,可以通过流程,实现了更加精准的工作流定制和完善的可复现性。每一个模块都有特定的的功能,我们可以通过调整模块连接达到不同的出图效果,特点如下: 1.对显存…

2024年 前端JavaScript入门到精通 第一天

主要讲解JavaScript核心知识,包含最新ES6语法,从基础到API再到高级。让你一边学习一边练习,重点知识及时实践,同时每天安排大量作业,加深记忆,巩固学习成果。 1.1 基本软件与准备工作 1.2 JavaScript 案例 …

C语言rand随机数知识解析和猜数字小游戏

rand随机数 rand C语言中提供了一个可以随机生成一个随机数的函数&#xff1a;rand&#xff08;&#xff09; 函数原型&#xff1a; int rand(void);rand函数返回的值的区间是&#xff1a;0~RAND_MAX(32767)之间。大部分编译器都是32767。 #include<stdlib.h> int ma…

hummingbird,一个便于将模型部署到边缘设备的Python库!

前言 随着人工智能和机器学习的快速发展&#xff0c;将训练好的模型部署到生产环境中成为了一个重要的任务。而边缘计算设备&#xff0c;如智能手机、嵌入式系统和物联网设备&#xff0c;也需要能够运行机器学习模型以进行实时推理。Python Hummingbird 是一个强大的工具&…

Java学习笔记2024/2/8

面向对象 //面向对象介绍 //面向: 拿、找 //对象: 能干活的东西 //面向对象编程: 拿东西过来做对应的事情 //01-如何设计对象并使用 //1.类和对象 //2.类的几个不错注意事项 1. 类和对象 1.1 类和对象的理解 客观存在的事物皆为对象 &#xff0c;所以我们也常常说万物皆对…

基于springboot会员制医疗预约服务管理信息系统源码和论文

会员制医疗预约服务管理信息系统是针对会员制医疗预约服务管理方面必不可少的一个部分。在会员制医疗预约服务管理的整个过程中&#xff0c;会员制医疗预约服务管理系统担负着最重要的角色。为满足如今日益复杂的管理需求&#xff0c;各类的管理系统也在不断改进。本课题所设计…

Web课程学习笔记--JavaScript操作DOM常用的API

JavaScript操作DOM常用的API 1 什么是DOM 文档对象模型 (DOM) 是HTML和XML文档的编程接口。它提供了对文档的结构化的表述&#xff0c;并定义了一种方式可以使从程序中对该结构进行访问&#xff0c;从而改变文档的结构&#xff0c;样式和内容。 文档对象模型 (DOM) 是对HTML文…

springboot 拦截器

定义 拦截器类似于javaweb中filter 功能 注意: 只能拦截器controller相关的请求 作用 举一个例子&#xff0c;例如我们在Controller中都有一段业务逻辑&#xff0c;这样我们就可以都统一放在拦截器中 因此拦截器的作用就是将controller中共有代码放入到拦截器中执行,减少co…

【算法与数据结构】496、503、LeetCode下一个更大元素I II

文章目录 一、496、下一个更大元素 I二、503、下一个更大元素II三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、496、下一个更大元素 I 思路分析&#xff1a;本题思路和【算法与数据结构】739、LeetCode每日温度类似…

【VTKExamples::PolyData】第二十四期 InterpolateTerrain

很高兴在雪易的CSDN遇见你 VTK技术爱好者 QQ:870202403 前言 本文分享VTK样例InterpolateTerrain,希望对各位小伙伴有所帮助! 感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步! 你的点赞就是我的动力(^U^)ノ~YO 1. InterpolateTerrain 输出: Interp…

精灵图,字体图标,CSS3三角

精灵图 1.1为什么需要精灵图 一个网页中往往会应用很多小的背景图像作为修饰&#xff0c;当网页中的图像过多时&#xff0c;服务器就会频繁的接受和发送请求图片&#xff0c;造成服务器请求压力过大&#xff0c;这将大大降低页面的加载速度。 因此&#xff0c;为了有效地减少…

深入Java容器:概览、设计模式与源码分析

深入Java容器&#xff1a;概览、设计模式与源码分析 Java 容器一、概览Collection1. Set2. List3. Queue Map 二、容器中的设计模式迭代器模式适配器模式 三、源码分析ArrayList1. 概览2. 扩容3. 删除元素4. 序列化5. Fail-Fast Vector1. 同步2. 扩容3. 与 ArrayList 的比较4. …

Java与MySQL的精准结合:打造高效审批流程

1流程思路分析 审批流程&#x1f431;‍&#x1f4bb; 1.串行流程 当前节点审批完成后&#xff0c;下一次节点才能进行操作&#xff0c;例如经理通过之后&#xff0c;总监才能审批&#xff1b; 2.并行流程 一个审批节点需要多人联审。一般有两种方式&#xff1a;会签、或签…