负载均衡,反向代理,动静分离(静态资源通过nginx处理)
轮询,加权轮询,ip哈希(建议使用redis做seesson共享)
配置
全局/event/http(反向代理配置/负载均衡配置)
80 http
443 https
正向代理 客户端
反向代理 服务器 无感知
1 在项目中一般是配置configure文件
2 源码实现
源码实现主要包括两部分 2.1)进程模型; 2.2) nginx内存:共享内存(nginx是多进程的,进程之间的通信通过共享内存),内存池
惊群问题
不影响业务
产生无效的唤醒
解决方法
使用共享内存,只保证一个fd加入到epoll里
内存池:大块,小块
大块,释放
小块, 统一释放(释放内存池)
局限性:对小块不做回收 (相当于内存泄漏)
均衡点(取舍):小块回收的成本和性能(内存的损耗)
因为内存池的生命周期比较短,连接断开时销毁,可以达到均衡
每个请求时独立的,多个进程之间没有通信
只释放大块,小块只有destroy
ngx_int_t
ngx_pfree(ngx_pool_t *pool, void *p)
{
ngx_pool_large_t *l;
for (l = pool->large; l; l = l->next) {
if (p == l->alloc) {
ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
"free: %p", l->alloc);
ngx_free(l->alloc);
l->alloc = NULL;
return NGX_OK;
}
}
return NGX_DECLINED;
}
void
ngx_destroy_pool(ngx_pool_t *pool)
{
ngx_pool_t *p, *n;
ngx_pool_large_t *l;
ngx_pool_cleanup_t *c;
for (c = pool->cleanup; c; c = c->next) {
if (c->handler) {
ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
"run cleanup: %p", c);
c->handler(c->data);
}
}
#if (NGX_DEBUG)
/*
* we could allocate the pool->log from this pool
* so we cannot use this log while free()ing the pool
*/
for (l = pool->large; l; l = l->next) {
ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p", l->alloc);
}
for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {
ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
"free: %p, unused: %uz", p, p->d.end - p->d.last);
if (n == NULL) {
break;
}
}
#endif
for (l = pool->large; l; l = l->next) {
if (l->alloc) {
ngx_free(l->alloc);
}
}
for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {
ngx_free(p);
if (n == NULL) {
break;
}
}
}
大块,小块,内存池分如下
struct ngx_pool_large_s {
ngx_pool_large_t *next;
void *alloc;
};
typedef struct {
u_char *last;
u_char *end;
ngx_pool_t *next;
ngx_uint_t failed;
} ngx_pool_data_t;
struct ngx_pool_s {
ngx_pool_data_t d;
size_t max;
ngx_pool_t *current;
ngx_chain_t *chain;
ngx_pool_large_t *large;
ngx_pool_cleanup_t *cleanup;
ngx_log_t *log;
};