松岗做网站价格/怎样写营销策划方案
文章目录
- nginx运行模式与进程模式
- 进程模式流程图
- 默认初始化运行模式与进程模式(宏展开)
- cpu_affinity多CPU绑定合理性判定
- Nginx的daemon创建(os/unix/ngx_daemon.c)
- 运行模式、进程模式启动
- 多进程模式下master处理流程
- 设置进程信号、初始化信号掩码、屏蔽相关信号
- 调用ngx_start_worker_processes函数派生Worker进程
- 创建cache进程,用于缓存管理
- 进入主循环,通过sigsuspend使进程等待信号
- 调用ngx_start_worker_processes函数派生Worker进程
- ngx_pass_open_channel函数
- ngx_write_channel函数
- 讨论
nginx运行模式与进程模式
nginx有守护(daemon)模式与非守护(非daemon)模式两种模式,两种模式在运行后的区别在于:
- 守护模式:nginx启动后直接回到命令提示符界面,不接受任何的输入和输出,其父进程为Linux的init进程;启动nginx进程后,会使用fork创建子进程进行后续操作,启动进程会自动结束。
- 非守护模式:nginx启动后没有回到命令提示符界面,当nginx有输出时,会直接在终端输出,其父进程为bash。
进程模式分为单进程模式和多进程模式
进程模式流程图
默认初始化运行模式与进程模式(宏展开)
static char *ngx_core_module_init_conf(ngx_cycle_t *cycle, void *conf)//函数中(core/nginx.c文件中):
{ ………ngx_conf_init_value(ccf->daemon, 1); //守护进程,daemon守护方式ngx_conf_init_value(ccf->master, 1); //多进程模式………ngx_conf_init_value(ccf->worker_processes, 1); //默认一个worker………//worker进程绑定CPU设置合理性判断,用户名,文件锁等初始化return NGX_CONF_OK;
}//宏定义展开如下
#define NGX_CONF_UNSET -1
………
#define ngx_conf_init_value(conf, default) \ if (conf == NGX_CONF_UNSET) { \ conf = default; \ }
………static char *ngx_core_module_init_conf(ngx_cycle_t *cycle, void *conf)//函数中(core/nginx.c文件中):
{………//ngx_conf_init_value(ccf->daemon, 1)按宏展开;if (ccf->daemon == -1) {//守护进程,daemon守护方式ccf->daemon = 1; }//以下ngx_conf_init_value宏类似展开………return NGX_CONF_OK;
}
cpu_affinity多CPU绑定合理性判定
进行绑定时,必须cpu数目与worker进程数目相等,否则不好绑定
#if (NGX_HAVE_CPU_AFFINITY) //支持多CPU绑定if (!ccf->cpu_affinity_auto //非自动&& ccf->cpu_affinity_n //非0 && ccf->cpu_affinity_n != 1 //非1 && ccf->cpu_affinity_n != (ngx_uint_t) ccf->worker_processes) //与工作进程数相等 { //错误处理及记录;}
#endif
Nginx的daemon创建(os/unix/ngx_daemon.c)
- 创建一个子进程,自己(父进程)关闭结束;.
- 创建新的会话;
- 设置进程的umask为0;
- daemon模式下,没有输入输出;
- 返回
//创建新的会话
………
switch (fork())
{ case -1: ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "fork() failed"); return NGX_ERROR; case 0: break; //子进程default: exit(0); //父进程退出,结束}
………//在守护模式下没有输出,nginx采用重定向的方式对输出进行重定向
………
fd = open("/dev/null", O_RDWR);
if (fd == -1) { //错误记录处理, return NGX_ERROR;
}
if (dup2(fd, STDIN_FILENO) == -1) { //错误记录处理, return NGX_ERROR; } //将标准输入重定位到fd,即null设备
if (dup2(fd, STDOUT_FILENO) == -1) {//错误记录处理, return NGX_ERROR; } //将标准输出重定位到fd,即null设备
………
ngx_int_t ngx_daemon(ngx_log_t *log) //汇总与总结
{//定义变量;//创建一个子进程,自己(父进程)关闭结束;ngx_parent = ngx_pid; //ngx_pid为全局变量 ngx_pid = ngx_getpid(); if (setsid() == -1) { //创建新的会话 //错误处理与记录后返回;} umask(0);//设置掩码为0//daemon模式下,关闭标准输入与输出;
}
运行模式、进程模式启动
在Nginx的main函数最后,一切准备就绪后,根据ngx_process 值的指示,判定单/多进程模式
int ngx_cdecl main(int argc, char *const *argv)
{………//前期内存池等各种准备if (ngx_process == NGX_PROCESS_SINGLE) { //为0 ngx_single_process_cycle(cycle); //单进程模式} else //不为0{ ngx_master_process_cycle(cycle); //多进程模式}return 0;
}
多进程模式下master处理流程
- 设置进程信号、初始化信号掩码屏蔽相关信号。
- 调用ngx_start_worker_processes函数派生Worker进程;
- ngx_start_cache_manager_processes函数派生cache manager进程以及cache loader进程; cache进程用于缓存管理;
- 进入主循环,通过sigsuspend使进程等待信号;
- 待收到信号后进入ngx_signal_handler进行信号处理
设置进程信号、初始化信号掩码、屏蔽相关信号
//Nginx定义的几个常见信号
#define NGX_SHUTDOWN_SIGNAL QUIT //终端退出
#define NGX_TERMINATE_SIGNAL TERM //软件终止
#define NGX_NOACCEPT_SIGNAL WINCH //窗口大小改变
#define NGX_RECONFIGURE_SIGNAL HUP //终端挂起或终端控制进程结束
- nginx信号解析
#define ngx_signal_helper(n) SIG##n // 表示前后两个字符串合并(宏)
#define ngx_signal_value(n) ngx_signal_helper(n) //程序中使用的宏ngx_signal_value (NGX_RECONFIGURE_SIGNAL)//,经过宏展开后
1. ngx_signal_value ( HUP ),经过宏展开后
2. ngx_signal_helper( HUP ),再经过宏展开后
3. SIGHUP 这正是Linux的信号………//定义局部临时变量
sigemptyset(&set);
sigaddset(&set, SIGCHLD); //Linux信号标准名字
sigaddset(&set, SIGALRM); //Linux信号标准名字
sigaddset(&set, SIGIO); //Linux信号标准名字
sigaddset(&set, SIGINT); //Linux信号标准名字
sigaddset(&set, ngx_signal_value(NGX_RECONFIGURE_SIGNAL)); //Linux信号别名
sigaddset(&set, ngx_signal_value(NGX_REOPEN_SIGNAL));
sigaddset(&set, ngx_signal_value(NGX_NOACCEPT_SIGNAL));
sigaddset(&set, ngx_signal_value(NGX_TERMINATE_SIGNAL));
sigaddset(&set, ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
sigaddset(&set, ngx_signal_value(NGX_CHANGEBIN_SIGNAL));
if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) { //若新增屏蔽(搁置)信号集合set 失败 //错误处理并记录
}
sigemptyset(&set);//清空信号集,以便后面使用
………
调用ngx_start_worker_processes函数派生Worker进程
………
ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
ngx_start_worker_processes(cycle, ccf->worker_processes, NGX_PROCESS_RESPAWN);
………
创建cache进程,用于缓存管理
………
ngx_start_cache_manager_processes(cycle, 0);
………
进入主循环,通过sigsuspend使进程等待信号
………
for(;;){………//设置时钟sigsuspend(&set); ngx_time_update();//更新时钟………
}
调用ngx_start_worker_processes函数派生Worker进程
多进程模式下Worker进程的作用(os/unix/ ngx_process_cycle.c)
- 读取请求、解析请求、处理请求,产生结果后,返回给客户,最后断开连接。
- 一个请求在一个且仅在该worker内处理完成;
- ngx_start_worker_processes函数调用ngx_spawn_process函数派生worker进程.
ngx_start_worker_processes函数的主要功能及其过程如下:
- 局部临时变量定义。如创建一个ngx_channel_t 变量ch,并将ch的command置为NGX_CMD_OPEN_CHANNEL;表示新建一个进程;
- 循环创建n个worker进程;
- 调用ngx_spawn_process创建一个worker进程,设置ngx_process_slot 值;
- 为了ngx_processes数组的值同步,设置好ch的其它字段的值,
- 调用ngx_pass_open_channel广播,使得以前创建的进程,更新ngx_processes数据;
- 重复,3~5,直至n个worker创建完成。
//第三个参数type
#define NGX_PROCESS_NORESPAWN -1 //子进程退出,父进程不重启
#define NGX_PROCESS_JUST_SPAWN -2 //区分刚建的子进程与其它子进程
#define NGX_PROCESS_RESPAWN -3//子进程退出,父进程重启
#define NGX_PROCESS_JUST_RESPAWN -4//区分刚建的子进程与其它子进程,子进程退出,父进程重启
#define NGX_PROCESS_DETACHED -5 //新派生进程与父进程脱离关系//第二个参数n :创建worker进程的总数
static voidngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n, ngx_int_t type)struct ngx_cycle_s { void ****conf_ctx; //保持所有模块的配置结构体ngx_pool_t *pool; //内存池ngx_log_t *log; //日志信息ngx_log_t new_log; ngx_uint_t log_use_stderr; /* unsigned log_use_stderr:1; */ ngx_connection_t **files; //文件句柄ngx_connection_t *free_connections; //可用连接池ngx_uint_t free_connection_n;//可用连接池总数ngx_module_t **modules; //模块信息ngx_uint_t modules_n; ngx_uint_t modules_used; /* unsigned modules_used:1; */ ngx_queue_t reusable_connections_queue; //再利用连接队列ngx_uint_t reusable_connections_n; //再利用连接数ngx_array_t listening; //被监听端口ngx_array_t paths; //操作目录ngx_array_t config_dump; ngx_rbtree_t config_dump_rbtree; ngx_rbtree_node_t config_dump_sentinel; ngx_list_t open_files; //打开文件ngx_list_t shared_memory; //共享文件ngx_uint_t connection_n; //当前进程中所有连接对象的总数ngx_uint_t files_n;//代开文件个数ngx_connection_t *connections; //指向当前进程中的所有连接对象 ngx_event_t *read_events; //读事件ngx_event_t *write_events; //写事件ngx_cycle_t *old_cycle; //old cycle指针ngx_str_t conf_file; //配置文件ngx_str_t conf_param; //配置参数ngx_str_t conf_prefix; //配置前缀ngx_str_t prefix; //前缀ngx_str_t lock_file; //用于进程间同步的文件锁ngx_str_t hostname;//主机名
};
ngx_channel_t结构体
//ngx_channel_t 的command
#define NGX_CMD_OPEN_CHANNEL 1 //新建
#define NGX_CMD_CLOSE_CHANNEL 2 //关闭
#define NGX_CMD_QUIT 3 //退出
#define NGX_CMD_TERMINATE 4 //终止
#define NGX_CMD_REOPEN 5 //重新打开(重启)
typedef struct { ngx_uint_t command; //命令ngx_pid_t pid; //进程号ngx_int_t slot; // ngx_processes 数组中worker进程下标ngx_fd_t fd;//保存用于socketpair全双工的socket
} ngx_channel_t;
ngx_processes数组
作用有以下几个方面:
(1)保存创建进程的有关信息;
(2)便于worker进程间通信;
(3)便于worker进程与master进程间通信;
ngx_process_t ngx_processes[NGX_MAX_PROCESSES];typedef struct { ngx_pid_t pid; //worker进程的PIDint status; //状态ngx_socket_t channel[2]; //worker与master之间通信的socketpair ngx_spawn_proc_pt proc; //回调函数void *data; // proc回调函数的参数char *name; //worker子进程的名字unsigned respawn:1; //是否重启unsigned just_spawn:1; //是否刚创建unsigned detached:1; //是否脱离unsigned exiting:1; unsigned exited:1;
} ngx_process_t;
static voidngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n, ngx_int_t type){
………// 创建并初始化ngx_channel_t结构体类型ch;
ngx_channel_t ch;
ch.command = NGX_CMD_OPEN_CHANNEL;
for (i = 0; i < n; i++) { //依次创建n个worker进程ngx_spawn_process(cycle, ngx_worker_process_cycle, (void *) (intptr_t) i, "worker process", type);//调用 ngx_spawn_process函数,创建worker进程,其信息ngx_processes数组ngx_process_slot 元素的中; ch.pid = ngx_processes[ngx_process_slot].pid; ch.slot = ngx_process_slot; ch.fd = ngx_processes[ngx_process_slot].channel[0]; //刚创建进程的写端给其它进程,便于后续通信ngx_pass_open_channel(cycle, &ch); //调用ngx_pass_open_channel广播(这是有linux的进程机制决定的,fork时父子进程会共享内存,当进程对内存内容进行修改时,内核会复制一份数据到另一片内存时,这时前后的内容会不一致,所以才需要广播)
}
}
ngx_spawn_process函数
- 在ngx_processes数组中找到一个保存worker进程信息的元素下标s;①如果respawn大于0, respawn就是s;②如果不大于0,从ngx_processes数组中找到其元素的pid成员为-1的(空闲)元素,该元素就是的数组下标就是s;但该s不能超过最大worker范围。
if (respawn >= 0)
{ s = respawn; // ①}
else
{ // ②,遍历ngx_processes数组,确定sfor (s = 0; s < ngx_last_process; s++) { if (ngx_processes[s].pid == -1) { break; } } if (s == NGX_MAX_PROCESSES) { //最大为1024 //超过最大worker数限制,错误处理并记录return NGX_INVALID_PID; }
}
- 如果respawn不是NGX_PROCESS_DETACHED,即派生子进程与父进程不是非脱离关系,①创建通信socketpair, ②以非阻塞方式设置读写端, ③将写端设置为异步写, ④并将写端的SIGIO以及SIGURG信号的属主设为父进程; ⑤设置Master、worker进程执行exec()函数后,关闭socket。
①创建通信socketpair,if (respawn != NGX_PROCESS_DETACHED) {//2,如果非关系成立if (socketpair(AF_UNIX, SOCK_STREAM, 0, ngx_processes[s].channel) == -1) // ①{//错误处理并记录;return NGX_INVALID_PID; }②以非阻塞方式设置读写端,if (ngx_nonblocking(ngx_processes[s].channel[0]) == -1) { //设置写端 //错误处理并记录;return NGX_INVALID_PID; }③将写端设置为异步写,on = 1; if (ioctl(ngx_processes[s].channel[0], FIOASYNC, &on) == -1) { // ③ // 错误处理并记录;return NGX_INVALID_PID; }④并将写端的SIGIO以及SIGURG信号的属主设为ngx_pid(父进程);if (fcntl(ngx_processes[s].channel[0], F_SETOWN, ngx_pid) == -1) { // ④ // 错误处理并记录;return NGX_INVALID_PID; }⑤设置Master、worker进程执行exec()函数后,关闭socket。
if (fcntl(ngx_processes[s].channel[1], F_SETFD, FD_CLOEXEC) == -1) { // ⑤ // 错误处理并记录;return NGX_INVALID_PID; }//以下设置当前子进程的socket,Master进程用于监听
ngx_channel = ngx_processes[s].channel[1];//给全局变量ngx_channel 赋值
}
- 如果respawn是NGX_PROCESS_DETACHED,设置该worker的通信通道都为-1;
else//是2的if的else分支,否则,则是NGX_PROCESS_DETACHED脱离关系{ ngx_processes[s].channel[0] = -1; //创建的是master,通信pair置为-1
ngx_processes[s].channel[1] = -1; }
- fork派生worker进程;
//为ngx_start_worker_processes函数记下ngx_process_slot 值ngx_process_slot = s; //ngx_process_slots是全部变量pid = fork(); //派生子进程
- worker子进程执行回调proc;
switch (pid) { case -1: 错误处理并记录;return NGX_INVALID_PID; case 0: //5,子进程执行回调函数procngx_parent = ngx_pid; ngx_pid = ngx_getpid(); proc(cycle, data); break; default: break; //父进程往后执行}
- 父进程填充worker子进程的信息到ngx_processes数组s元素中;
ngx_processes[s].pid = pid; //ngx_processes[s].exited = 0;
f (respawn >= 0) { //如果是重启子进程,返回return pid; }
ngx_spawn_process(cycle, ngx_worker_process_cycle, (void *) (intptr_t) i, "worker process", type);1.第一个参数: cycle, ngx_start_worker_processes函数
2.第二个参数:回调函数ngx_worker_process_cycle,该函数在os/unix/ ngx_process_cycle.c中定义;
3.第三个参数:i,即第几个worker
4.第四个参数:worker进程名字
5.第五个参数:类型,来自ngx_start_worker_processes函数的形参
ngx_pass_open_channel函数
遍历ngx_processes数组广播,对每个worker子进程发送信息。
static void ngx_pass_open_channel(ngx_cycle_t *cycle, ngx_channel_t *ch):
- 对每个非刚创建、不存在进程以及父进程socket关闭的子进程;
- 调用ngx_write_channel发送消息内容;
typedef struct { ngx_uint_t command; //命令,见下页ngx_pid_t pid; //进程号ngx_int_t slot; // ngx_processes 数组中worker进程下标ngx_fd_t fd;//保存用于socketpair全双工的socket
} ngx_channel_t;
static void ngx_pass_open_channel(ngx_cycle_t *cycle, ngx_channel_t *ch)
{for (i = 0; i < ngx_last_process; i++) { //过滤刚建的子进程、不存在的子进程以及关闭socket的子进程if (i == ngx_process_slot || //刚刚创建的ngx_processes[i].pid == -1 || //没有进程数据的数组元素ngx_processes[i].channel[0] == -1) //无法通信了{ continue; } .......... //给每个子进程的父进程发送刚建进程的worker信息ngx_write_channel(ngx_processes[i].channel[0], ch, sizeof(ngx_channel_t), cycle->log); }
}
ngx_write_channel函数
- 构造struct msghdr 类型msg;//Linux系统层次接口
- 调用sendmsg发送msg;//Linux系统层次接口
ngx_int_tngx_write_channel(ngx_socket_t s, ngx_channel_t *ch, size_t size, ngx_log_t *log)
{ssize_t n; //声明所需变量ngx_err_t err; struct iovec iov[1]; struct msghdr msg;
……iov[0].iov_base = (char *) ch; //构造msgiov[0].iov_len = size; msg.msg_name = NULL; msg.msg_namelen = 0; msg.msg_iov = iov; msg.msg_iovlen = 1; n = sendmsg(s, &msg, 0);//发送msg,Linux编程接口……//错误处理等return NGX_OK;
}
讨论
- 为什么nginx使用的是进程不是线程
是因为 Nginx 要保证高可用性,多线程之间会共享地址空间,当某一个第三方模块引发了一个段错误时,就会导致整个 Nginx 进程挂掉。而采用多进程模型不会出现这个问题
相关文章:

nginx 进程模型
文章目录 nginx运行模式与进程模式进程模式流程图默认初始化运行模式与进程模式(宏展开)cpu_affinity多CPU绑定合理性判定Nginx的daemon创建(os/unix/ngx_daemon.c)运行模式、进程模式启动 多进程模式下master处理流程设置进程信号、初始化信号掩码、屏蔽…...

TypeScript - 枚举类型 -字符型枚举
什么是枚举 枚举就是有固定的元素的一个对象。 对象的元素可以直接列举出来。 什么是字符型枚举 字符型枚举,就是元素的值是字符串。 就这么简单。 定义一个我看看 来,让我们实际看一下字符型的枚举。 // 定义字符型枚举 enum COLOR2{RED red,BLUE blu…...

分布式锁-Redis红锁解决方案
一 分布式锁的概念 1:概念 分布式锁(多服务共享锁) 在分布式的部署环境下,通过锁机制来让多客户端互斥的对共享资源进行访问控制分布式系统不同进程共同访问共享资源的一种锁的实现。如果不同的系统或同一个系统的不同主机之间共…...

【Ubuntu 终端终结者Ctrl shift e无法垂直分页解决办法】
Ubuntu 终端终结者Ctrl shift e无法垂直分页解决办法 错误原因解决办法 错误原因 这是因为ibus输入法有一个快捷键占用了这个终端终结者的快捷键 解决办法 打开命令行输入 ibus-setup进入到如下页面随后将其中的表情注释的快捷键删除即可...

Error: error:0308010C:digital envelope routines::unsupported
Error: error:0308010C:digital envelope routines::unsupported 问题描述: 使用 npm run dev 或者 yarn run dev 时 报错:Error: error:0308010C:digital envelope routines::unsupported PS D:\Project\dlspeed_all\GS-IMS\ruoyi-ui> npm run de…...

RTMP在智能眼镜行业应用方案有哪些?
方案示例 视频直播:智能眼镜通常具有摄像头和显示屏,可以实时拍摄和显示视频。RTMP协议可以用于将智能眼镜拍摄的视频传输到服务器,以便其他用户可以实时观看。远程协作:智能眼镜可以用于远程协作,例如在医疗、建筑等…...

【每日一题】合并两个有序数组
链接奉上:合并两个有序数组 目录 直接合并后排序:思路:代码实现: 双指针思路:代码实现: 直接合并后排序: 思路: 将nums2直接合并到nums1后边,并进行排序 代码实现&…...

MySQL---表的增查改删(CRUD进阶)
文章目录 数据库约束表的设计一对一一对多多对多 新增查询聚合查询分组查询联合查询内连接外连接自连接子查询合并查询 数据库约束 数据库约束就是指:程序员定义一些规则对数据库中的数据进行限制。这样数据库会在新增和修改数据的时候按照这些限制,对数…...

《HelloGitHub》第 91 期
兴趣是最好的老师,HelloGitHub 让你对编程感兴趣! 简介 HelloGitHub 分享 GitHub 上有趣、入门级的开源项目。 github.com/521xueweihan/HelloGitHub 这里有实战项目、入门教程、黑科技、开源书籍、大厂开源项目等,涵盖多种编程语言 Python、…...

jvm线上异常排查流程
1. Linux命令 jps 找出当前运行实例 2. jinfo -flags pid(java运行id) 打印出当前设置的jvm内存参数情况 3.jstat -gcutil pid 1000 10 每秒打印一次当前jvm的gc运行情况,一共打印10次 4.将gc日志下载进行分析:到底是因为什么原因导致一直…...

python项目之酒店客房入侵检测系统的设计与实现
项目简介 酒店客房入侵检测系统的设计与实现实现了以下功能: 1、控制台: 控制台是整个系统的首页面。在控制台中,酒店的客房管理人员能够在该页面中查看到当前的空余客房数量、当前在店的客房人数、当前的已用客房数量、当前酒店全部的客房…...

C++ 学习系列 -- 标准库常用得 algorithm function
一 前言 c 标准库中提供了许多操作数据结构:vector、list、deque、map、set 等函数,学习并了解这些常用函数对于我们理解 c 的一些设计模式有着重要的作用。 二 常用的 algorithm function 源码 源代码位置: bits/stl_algo.h 1. accumu…...

[论文笔记]E5
引言 今天又带来一篇文本匹配/文本嵌入的笔记:Text Embeddings by Weakly-Supervised Contrastive Pre-training。中文题目是 基于弱监督对比预训练计算文本嵌入。 本篇工作提出了E5模型(EmbEddings from bidirEctional Encoder rEpresentations)。该模型以带弱监督信号的对…...

k8s 1.28版本:使用StorageClass动态创建PV,SelfLink 问题修复
k8s中提供了一套自动创建 PV 的机制,就是基于 StorageClass 进行的,通过 StorageClass 可以实现仅仅配置 PVC,然后交由 StorageClass 根据 PVC 的需求动态创建 PV。 问题: 使用 k8s 1.28版本,通过 kubectl get pv…...

漏洞复现-dedecms文件上传(CVE-2019-8933)
dedecms文件上传_CVE-2019-8933 漏洞信息 Desdev DedeCMS 5.7SP2版本中存在安全漏洞CVE-2019-8933文件上传漏洞 描述 Desdev DedeCMS(织梦内容管理系统)是中国卓卓网络(Desdev)公司的一套基于PHP的开源内容管理系统&#x…...

vue分片上传
<template><div><input type"file" id"input" /><button click"uploadFile">上传</button></div> </template><script lang"ts" setup> let chunkSize1024 * 1024,index0; const upl…...

【大数据Hive】hive 表数据优化使用详解
目录 一、前言 二、hive 常用数据存储格式 2.1 文件格式-TextFile 2.1.1 操作演示 2.2 文件格式 - SequenceFile 2.2.1 操作演示 2.3 文件格式 -Parquet 2.3.1 Parquet简介 2.3.2 操作演示 2.4 文件格式-ORC 2.4.1 ORC介绍 2.4.2 操作演示 三、hive 存储数据压缩优…...

京东平台数据分析(京东销量):2023年9月京东吸尘器行业品牌销售排行榜
鲸参谋监测的京东平台9月份吸尘器市场销售数据已出炉! 根据鲸参谋电商数据分析平台的相关数据显示,今年9月,京东吸尘器的销量为19万,环比下滑约12%,同比下滑约25%;销售额为1.2亿,环比下滑约11%&…...

基于springboot实现休闲娱乐代理售票平台系统项目【项目源码+论文说明】计算机毕业设计
基于springboot实现休闲娱乐代理售票平台系统演示 摘要 网络的广泛应用给生活带来了十分的便利。所以把休闲娱乐代理售票管理与现在网络相结合,利用java技术建设休闲娱乐代理售票系统,实现休闲娱乐代理售票的信息化。则对于进一步提高休闲娱乐代理售票管…...

jvm对象内存划分
写此篇博客源于面试问到内存分配的细节,然后不明白问的是什么。回过头发现以前看过这块内容,只是有些印象,但是无法描述清楚。 额外概念了解 jvm内存空间是逻辑上连续的虚拟地址空间(虚拟内存中的概念)映射到物理内存…...

网络原理之TCP/IP
文章目录 应用层传输层UDP协议TCP协议TCP 的工作机制1. 确认应答2. 超时重传3. 连接管理TCP 的建立连接的过程(三次握手),和断开连接的过程(四次挥手)TCP 断开连接, 四次挥手 3. 滑动窗口5. 流量控制6. 拥塞控制7. 延时应答8. 捎带应答9. 面向字节流10. 异常情况 本章节主要讨论…...

Docker:数据卷挂载
Docker:数据卷挂载 1. 数据卷2. 数据卷命令补充 1. 数据卷 数据卷(volume)是一个虚拟目录,是容器内目录与宿主机目录之间映射的桥梁。 Nginx容器有自己独立的目录(Docker为每个镜像创建一个独立的容器,每个容器都是基于镜像创建的运行实例),…...

你会处理 go 中的 nil 吗
对于下面这段代码,我们知道 i 实际上的值就是 nil,所以 i nil 会生效 func main() {var i *int nilif i nil {fmt.Println("i is nil") // i is nil} }现在换一种写法,我们将 i 的类型改成 interface{},i nil 依然…...

高级深入--day42
注意:模拟登陆时,必须保证settings.py里的 COOKIES_ENABLED (Cookies中间件) 处于开启状态 COOKIES_ENABLED True 或 # COOKIES_ENABLED False 策略一:直接POST数据(比如需要登陆的账户信息) 只要是需要提供post数据的ÿ…...

mysql 计算两个坐标距离
方式一:st_distance_sphere 计算结果单位米 SELECT *, st_distance_sphere(point(lng,lat),point(lng,lat)) as distance FROM table mysql 版本5.7 以上 方式二:st_distance 计算结果单位是度 SELECT *, (st_distance(point(lng,lat),point(lng4,lat…...

String、StringBuffer、StringBuilder和StringJoiner
String、StringBuffer、StringBuilder和StringJoiner都是用于处理字符串的类,但它们在性能和使用方式上有一些区别。 String String是不可变的类,一旦创建就不能被修改。对String进行拼接或修改时,实际上是创建了一个新的String对象。适用于…...

【数据结构】插入排序
⭐ 作者:小胡_不糊涂 🌱 作者主页:小胡_不糊涂的个人主页 📀 收录专栏:浅谈数据结构 💖 持续更文,关注博主少走弯路,谢谢大家支持 💖 直接插入、希尔排序 1. 什么是排序2…...

Photoshop使用笔记总目录
Photoshop基础学习之工具学习 一、【Photoshop界面认识】 二、【 Photoshop常用快捷键】 三、【色彩模式与颜色填充】 四、【选区】 五、【视图】 六、【常用工具组】 七、【套索工具组】 八、【快速选择工具组】 九、【裁剪工具组】 十、【图框工具组】 十一、【吸取…...

最近面试遇到的高频面试题
大家好,我是 jonssonyan 互联网寒冬?金九银十真的不存在了么?虽说现在行情是差了一些,面试机会少了一些,但是大部分公司还是或多或少的招人,春招秋招都在进行。有人离职就有人入职。所以如果你还没约到面试…...

负载均衡有哪些算法,分别在nginx中如何配置?
负载均衡是用于分发传入的网络流量到多个后端服务器的技术,以确保无单个服务器过载,从而提高应用的可用性和响应时间。以下是一些常用的负载均衡算法,以及如何在Nginx中配置它们: 轮询 (Round Robin): 简介:…...