leevis.com icon indicating copy to clipboard operation
leevis.com copied to clipboard

Blog

Results 122 leevis.com issues
Sort by recently updated
recently updated
newest added

### EPOLLRDHUP是什么意思 `epoll_wait` 返回的`epoll_event` 的`events` 的`EPOLLRDHUP`被置位是什么意思呢,表示对端调用close()关闭socket连接或调用shutdown(SHUT_WR)关闭对端的写。 ### nginx是如何判断内核支持该错误的 这个参数应该是个新东西,也就是说不是所有的内核都支持。nginx又是怎么判断内核是否支持的呢? 在auto/os/linux 有这样一段代码,调用auto/feature 把ngx_feature_test的内容调用gcc编译一下,如果编译(且运行)成功则该系统支持该参数。 ``` ngx_feature="EPOLLRDHUP" ngx_feature_name="NGX_HAVE_EPOLLRDHUP" ngx_feature_run=no ngx_feature_incs="#include " ngx_feature_path= ngx_feature_libs= ngx_feature_test="int efd = 0, fd = 0; struct epoll_event ee;...

nginx
socket

在ls回调函数ngx_http_init_connection中。如果支持http2.0协议,则可读事件的回调函数覆写为ngx_http_v2_init。当连接可读时,回调该函数。 ### ngx_http_v2_init + 创建连接结构体h2c,类型为ngx_http_v2_connection_t,一个连接对应一个结构体。 + 创建h2c->streams_index stream列表。 + 调用ngx_http_v2_send_settings构件[SETTINGS帧](http://httpwg.org/specs/rfc7540.html#SETTINGS),设置SETTINGS_MAX_CONCURRENT_STREAMS、SETTINGS_INITIAL_WINDOW_SIZE、SETTINGS_MAX_FRAME_SIZE。因为该帧是面向链接的而不是流,因此流标识必须为0(ngx_http_v2_write_sid(buf->last, 0))。 构件好的帧被保存到h2c->last_out上,h2c类型为ngx_http_v2_connection_s。 + 调用ngx_http_v2_send_window_update函数构件[WINDOW_UPDATE帧](http://httpwg.org/specs/rfc7540.html#WINDOW_UPDATE),结果被保存到h2c->last_out上。 + 设置state回调函数为ngx_http_v2_state_preface。 + 可读事件回调函数为ngx_http_v2_read_handler,可写事件回调函数为ngx_http_v2_write_handler。 + 调用可读事件的回调函数。 ### ngx_http_v2_read_handler + 调用recv封装的函数读取socket缓存区内容。 + 调用state回调函数ngx_http_v2_state_preface。判断读取的内容是否为`PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n`,不是则返回[Error Codes帧](http://httpwg.org/specs/rfc7540.html#ErrorCodes)错误码为PROTOCOL_ERROR。 +...

### 概述 作为代理服务器,把客户端真实ip传递到后端有时候是需要的。 Haproxy作者设计了代理协议、在7层http协议又可以通过header头传递。详细请看《[nginx的proxy protocol实现](https://github.com/vislee/leevis.com/issues/141)》。而在Linux 2.6.24以后,socket增加了一个选项[IP_TRANSPARENT](http://man7.org/linux/man-pages/man7/ip.7.html)可以接受目的地址没有配置的数据包,也可以发送原地址不是本地地址的数据包。可以通过该特性实现4层以上的透明代理。注意:需要设置路由。 ### 代码实现 nginx通过指令 ` proxy_bind $remote_addr transparent; ` 让代理服务器绑定真实的客户端ip向上游发起请求连接。 #### 指令解析 nginx 在http模块和stream均支持该指令,逻辑基本相似。来看下stream模块的指令解析。 ```c static char * ngx_stream_proxy_bind(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) {...

nginx

slab内存分配是linux系统的一个算法,如:[linux slab分配器剖析](https://www.ibm.com/developerworks/cn/linux/l-linux-slab-allocator/index.html)。 ngx的slab实现在src/core/ngx_slab.h|c这两个文件中。 ```c typedef struct { ngx_shmtx_sh_t lock; // ngx中共享内存都是由ngx_init_zone_pool初始化,该函数中最小分配内存就是8B size_t min_size; // 1 start 是可分配内存块的首地址对齐在pagesize边界 // page - pool->pages 是第几个块内存块。 // (((page) - (pool)->pages) pages) start) void ngx_slab_init(ngx_slab_pool_t...

nginx

### 概述 常常看到github好多项目都有绿色的小图标表示编译结果和码覆盖率。 ### 配置 #### 自动编译 在https://travis-ci.org 用github账号登录。 travis会自动同步github公开的仓库。找到对应的项目激活。 在github仓库添加.travis.yml文件,文件内容参考travis文档。例子可以看我[ngx_stream_ipdb_module的.travis.yml](https://github.com/vislee/ngx_stream_ipdb_module/blob/master/.travis.yml) 写好.travis.yml文件,在git push后,travis就会自动拉去github上的项目编译。 在travis找到对应的项目,项目后面跟了一个build的图标,点击图标就会弹出一个框, 选择分支和markdown,把对应的代码粘贴到github.com仓库readme.md,就可以显示绿色的编译状态的图标了。 例如下面是我ngx_stream_ipdb_module项目的编译结果。 ``` [![Build Status](https://travis-ci.org/vislee/ngx_stream_ipdb_module.svg?branch=master)](https://travis-ci.org/vislee/ngx_stream_ipdb_module) ``` #### 代码覆盖率 代码覆盖率 https://coveralls.io 只负责展示结果,真正的覆盖率测试还是需要你自己在.travis.yml中指定。 当然coveralls.io也提供其他方式的配置。我们只看.travis.yml方式。 一般你需要有单元测试,单元测试完毕后,在.travis.yml的`after_success: ` 阶段生成https://coveralls.io展示的覆盖率结果。 同样你也需要用github账号注册[coveralls](https://coveralls.io)...

### 背景 PaaS平台提供了很多的服务,而各个服务的计费策略和计费项都有所不同,并且根据用户等级还会对某些服务的某些资源项有优惠啊,免费配额啊,分钟配额啊等等的需求。 因此,对计费服务是个大挑战,既要满足各种服务的计费策略,又要能够实时处理数据给用户展示和限制使用。具体的来说就是,计费服务需要根据用户的等级,应用的等级,用户的服务资源数据采取对应的优惠策略和计费策略,也需要检查用户的分钟使用量是否超出对应等级的配额,超过的还需要限制服务几分钟的使用。同时,又要对将来可能的计费策略和计费项做出可扩展。而云平台又有众多的应用跑在上面,每个服务的数据量有很大。 - 有这么多难点数据量又大,所以就需要一个合理的设计和取舍。 - 数据在源头汇总一次,以减轻对计费系统的压力,即每个应用的每个服务在每个机器上每分钟汇总一条数据。(相同的服务肯定是一组机器,一个应用在每分钟的请求量肯定会落在这一组机器的不同机器上,因此计费侧还是得汇总一次) - 分服务计费,以方便横向扩展。每个服务计费对应一个计费进程。 - 资源费用一致性,只要扣了费用,就要能找到对应的资源。计费采用线性的流式打标签的方法。只能单进程处理。 - 计费要处理不同的服务的计费策略,就要通过配置文件可以配置,否则就得在程序里写`if-else`。 - 计费项灵活可变。就要通过映射来做。 ### 设计 根据上述的特点,最终决定用golang写计费服务。整个计费服务分为4个业务逻辑子服务共10个环节和一个http子服务。每个子服务运行在一个goroutine中。逻辑子服务之间通过channel通信,计费逻辑子服务和http子服务之间通过共享内存通信。计费逻辑子服务完成计费的一些功能,http子服务提供一个运行时的查询。每个原始的子服务放在一个package中。所有的子服务的struct都要继承自一个baseSrv的服务,用以标准化子服务。 - pull resource subsrv : 拉取计费资源数据子服务。 - PullResDataCycle 拉取资源数据环节。 用来从消息队列中拉取对应服务的计费资源数据。 -...

### 概述 随着互联网的发展,openssl早期的协议支持不了新的需求。例如:单ip支持https多虚拟主机。 http2还是http1.1的协商等。 因此,需要在原来的协议上再扩展。 现在就来看下扩展的代码的。我们从SNI是如何支持的来看起。 ### 代码 根据上一篇的分析,从read_state_machine函数开始,调用ossl_statem_server_post_process_message函数再调用tls_post_process_client_hello再调用tls_early_post_process_client_hello,再调用tls_parse_all_extensions,该函数又调用tls_parse_extension。在这个函数根据调用了封装在ext_defs数组中的回调。 statem/extensions.c ```c /* Structure to define a built-in extension */ typedef struct extensions_definition_st { /* The defined type for the extension...

### 概述 在计算机世界里,虚拟是对真实高度的抽象让问题简单化的一种方式。 ### 虚拟网络设备 + veth pair 是一种网络虚拟设备,总是成对出现,类似于管道。两端都连接网络协议栈,但是可以连接不通的网络协议栈。docker桥接就会用到。 + bridge 是一个虚拟交换机。和veth pair不通,bridge有多个端口,工作在2层数据链路层,转发是要依靠mac地址识别的。 ### 附录: [数据包的接收](https://segmentfault.com/a/1190000008836467) [数据包的发送](https://segmentfault.com/a/1190000008926093)

### 概述 最近重构了个系统,大大小小的功能大概有几十个,正常和例外的情况大概有上百个。虽然有单元测试,但是上了线上验证这么多case是一件很耗时很繁琐的事情。我希望有个工具能像单元测试的功能,把所有单元测试的用例在灰度的机器回放一遍,没有问题再镜像流量比对,或者导入小流量灰度几天,逐渐放量。 ### 解决 我用golang写了个小工具,大概的流程是: + 发布包的时候把单元测试的配置以测试配置发布到灰度环境,当然要确保该配置不会影响线上正常的业务。 + 同时把单元测试的请求抽出来,生成一个case文件。 + 上线的时候,把机器从前端负载均衡摘除,上线后。用该工具把抽出来的case文件的请求回放一遍,该工具会自动比对请求结果。如果没有问题,灰度10%的流量。 #### 测试用例例子 ```json [ { "title": "Test01 redirect", "req": { "url": "/t/redirect/", "host": "www.test.com", "headers": { "x-request-type": "case_test"...

### ngx_waf + 编译 ./configure --prefix=/tmp/waf --add-dynamic-module=../ngx-http-waf-module --with-compat --with-cc-opt="-fprofile-arcs -ftest-coverage" --with-ld-opt="-lgcov" + 在nginx目录执行 lcov --directory . --zerocounters + prove . + lcov --directory ./objs/addon/ngx-http-waf-module/ --capture --output-file waf.info --base-directory . +...