源码走读rgw内置civetweb的参数初始化过程
1. 初始化civetweb时刻的参数传递
src/civetweb/civetweb.h
/* Start web server.
Parameters:
callbacks: mg_callbacks structure with user-defined callbacks.
options: NULL terminated list of option_name, option_value pairs that
specify Civetweb configuration parameters.
Side-effects: on UNIX, ignores SIGCHLD and SIGPIPE signals. If custom
processing is required for these, signal handlers must be set up
after calling mg_start().
Example:
const char *options[] = {
"document_root", "/var/www",
"listening_ports", "80,443s",
NULL
};
struct mg_context *ctx = mg_start(&my_func, NULL, options);
Refer to https://github.com/bel2125/civetweb/blob/master/docs/UserManual.md
for the list of valid option and their possible values.
Return:
web server context, or NULL on error. */
CIVETWEB_API struct mg_context *mg_start(const struct mg_callbacks *callbacks,
void *user_data,
const char **configuration_options);
civetweb启动时的参数初始化由mg_start函数实现,注意configuration_options为具体的配置参数,配置参数的介绍可以参考https://github.com/bel2125/civetweb/blob/master/docs/UserManual.md
2. rgw中对civetweb启动时的参数初始化
src/rgw/rgw_civetweb_frontend.cc
int RGWMongooseFrontend::run() {
char thread_pool_buf[32];
snprintf(thread_pool_buf, sizeof(thread_pool_buf), "%d",
(int)g_conf->rgw_thread_pool_size);
string port_str;
map<string, string> conf_map = conf->get_config_map();
conf->get_val("port", "80", &port_str);
conf_map.erase("port");
conf_map["listening_ports"] = port_str; #默认端口设置
set_conf_default(conf_map, "enable_keep_alive", "yes"); #默认开启了keepalive
set_conf_default(conf_map, "num_threads", thread_pool_buf); #从rgw_thread_pool_size这个配置项中读取对应的并发数
set_conf_default(conf_map, "decode_url", "no");
// Set run_as_user. This will cause civetweb to invoke setuid() and setgid()
// based on pw_uid and pw_gid obtained from pw_name.
string uid_string = g_ceph_context->get_set_uid_string();
if (!uid_string.empty()) {
conf_map.erase("run_as_user");
conf_map["run_as_user"] = uid_string;
}
const char *options[conf_map.size() * 2 + 1];
int i = 0;
for (map<string, string>::iterator iter = conf_map.begin();
iter != conf_map.end(); ++iter) {
options[i] = iter->first.c_str();
options[i + 1] = iter->second.c_str();
dout(20)<< "civetweb config: " << options[i] << ": "
<< (options[i + 1] ? options[i + 1] : "<null>") << dendl;
i += 2;
}
options[i] = NULL;
struct mg_callbacks cb;
memset((void *)&cb, 0, sizeof(cb));
cb.begin_request = civetweb_callback;
cb.log_message = rgw_civetweb_log_callback;
cb.log_access = rgw_civetweb_log_access_callback;
ctx = mg_start(&cb, &env, (const char **)&options);#启动civetweb
if (!ctx) {
return -EIO;
}
return 0;
} /* RGWMongooseFrontend::run */
通过RGWMongooseFrontend的run方法,实现了civetweb的启动参数初始化。
3. 几个比较有用的参数介绍
throttle
Limit download speed for clients. throttle is a comma-separated list of key=value pairs, where key could be:
* limit speed for all connections
x.x.x.x/mask limit speed for specified subnet
uri_prefix_pattern limit speed for given URIs
The value is a floating-point number of bytes per second, optionally followed by a k or m character, meaning kilobytes and megabytes respectively. A limit of 0 means unlimited rate. The last matching rule wins. Examples:
*=1k,10.0.0.0/8=0 limit all accesses to 1 kilobyte per second,
but give connections the from 10.0.0.0/8 subnet
unlimited speed
/downloads/=5k limit accesses to all URIs in `/downloads/` to
5 kilobytes per second. All other accesses are unlimited
可以实现针对不同的subnet和URL设置下载速度,在需要限速的场景下比较有用
access_control_list
An Access Control List (ACL) allows restrictions to be put on the list of IP addresses which have access to the web server. In the case of the Civetweb web server, the ACL is a comma separated list of IP subnets, where each subnet is pre-pended by either a - or a + sign. A plus sign means allow, where a minus sign means deny. If a subnet mask is omitted, such as -1.2.3.4, this means to deny only that single IP address.
Subnet masks may vary from 0 to 32, inclusive. The default setting is to allow all accesses. On each request the full list is traversed, and the last match wins. Examples:
-0.0.0.0/0,+192.168/16 deny all accesses, only allow 192.168/16 subnet
这个应该都比较熟了,ACL控制哪些subnet或者host可以访问
num_threads
Number of worker threads. Civetweb handles each incoming connection in a separate thread. Therefore, the value of this option is effectively the number of concurrent HTTP connections Civetweb can handle.
控制单个civetweb实例的最大并发数
allow_sendfile_call
This option can be used to enable or disable the use of the Linux sendfile system call. It is only available for Linux systems and only affecting HTTP (not HTTPS) connections if throttle is not enabled. While using the sendfile call will lead to a performance boost for HTTP connections, this call may be broken for some file systems and some operating system versions.
援引一段对sendfile特性的描述 sendfile() copies data between one file descriptor and another.Because this copying is done within the kernel, sendfile() is more efficient than the combination of read(2) and write(2), which would require transferring data to and from user space. 启动该特性以后部分数据复制操作将在内核内部完成,能够减少上下文切换带来的性能损耗。
http://man7.org/linux/man-pages/man2/sendfile.2.html
- 再论IBatisNet + Castle进行项目的开发
- 利用xml轻松读取web.config中的用户自定义节
- 分布式监控系统Zabbix-3.0.3-完整安装记录(3)-监控nginx,php,memcache,Low-level discovery磁盘IO
- python报错问题解决:'ascii' codec can't encode character
- 利用message queue实现aspx与winform通信, 并附完整示例
- 10招步骤保护IIS服务器安全
- Haproxy+Keepalived高可用环境部署梳理(主主和主从模式)
- Android-Universal-Image-Loader 图片异步加载类库的使用
- 工作组模式下专用队列(Private Queue)如何引用远程队列路径
- haproxy反向代理环境部署(http和https代理)
- 网站速度优化模块HttpCompressionModule
- mysql启动后随即关闭问题解决(ibdata1文件损坏导致)
- webvirtmgr-重命名kvm虚拟机的名称
- Lucene 2.0最基本的入门代码
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Flutter组件随笔练习
- TKE 容器健康检查最佳实践
- 微信小程序修改checkbox和radio的样式
- TRTC Android端开发接入学习之实现实时屏幕分享(四)
- Vue使用组件递归实现评论盖楼功能笔记
- 自监督注意力在密集光流估计中的应用
- SpringBoot+MyBatis+Spring 技术整合实现商品模块的CRUD操作
- 什么?面试官让我用ArrayList实现一个阻塞队列?
- A little fun with InnoDB multi-versioning(14.有关InnoDB多版本中的一个小问题)
- 聊聊java中的哪些Map:(八)ConcurrentSkipListMap源码分析
- littlevgl(Lvgl)最新版V7.4移植
- TiKV 源码解析系列文章(二十)Region Split 源码解析
- 轻松构建Tomcat源码
- Flutter中Contrainer 组件的宽高限制分析
- 10张图带你深入理解Docker容器和镜像