分类 AWS 下的文章

使用nginx的动态缓存proxy cache遇到性能问题

服务器:aws lightsail(8 GB RAM, 2 vCPUs, 80 GB SSD)
架构:nginx,go,redis,mongodb,mysql
出现的问题:cpu高(kswapd0居高不下),内存高,磁盘IO也不小,其中nginx proxy cache基本使用接近配置的最大值。

问题解决过程:
1.kswapd0(来源自网络介绍)
kswapd0进程的作用:它是虚拟内存管理中,负责换页的,操作系统每过一定时间就会唤醒kswapd ,看看内存是否紧张,如果不紧张,则睡眠,其实这也是 VPS 使用上的一个常见的问题了,通常是由 Apache 占用内存过多引起的。kswapd0 是系统的虚拟内存管理程序,如果物理内存不够用,系统就会唤醒 kswapd0 进程,由 kswapd0 分配磁盘交换空间作缓存,因而占用大量的 CPU 资源。看起来这部分没办法解决
2.mongodb
显然mongodb也是性能的一大瓶颈,目前数据冗余的不多,只能尽可能多的删除无用的数据,结合定时任务用shell脚本去删除,mongo 172.26.27.18:27017/ad ./rmdata.js,其中rmadata.js很简单,db.ad.remove({name:{$exists:true}}),清理后任然达不到效果,可能原因是mongodb删除数据后要调用repair,也有可能是故障并不是由mongodb造成的,因为他数据量并不是很大
3.go程序问题
目前排除,因为这段时间并没有上线新的代码
4.nginx问题
结果查询日志发现,有大量的EXPIRED和miss的,这两部分加起来超过70%了,显然缓存没启到太大的作用,在加上,nginx本身要维护他们的过期,会频繁的IO。

解决问题:
根绝接口情况,显示的设置proxy_cache_key,默认的是包含所有的参数,会造成缓存量大,命中率低,我根据接口的访问量情况和参数情况,为访问量大的定制这些缓存key,例如:proxy_cache_key "$scheme$host$uri$arg_lo$arg_ver$arg_lg";
重启后问题解决
注意:此部分没有考虑断点续传的问题

参考:(整理自网络)
proxy_cache_path /dev/shm/ciika levels=1:2 keys_zone=cache_zone:4000m max_size=4g inactive=100m;

  1. proxy_temp_path和proxy_cache_path必须指定为同一分区。
  2. 参数levels=1:2 指定缓存空间为二级hash目录,第一级为1个字符,第二级为2个字符,比如/7/c2。
  3. 参数keys_zone=cache_web:16m 用户存放key和元数据的缓存区间,命名为cache_web,16m大小。
  4. 参数inactive=1h 如果资源在1h内未被请求,从缓存区中清除。
  5. 参数max_size=512m 指定本地缓存空间的大小,如果资源过于庞大时,按照LRU算法进行清除。
    location的设置:
    location /app/list {
    proxy_ignore_headers "Set-Cookie";
    proxy_ignore_headers "Cache-Control";
    proxy_ignore_headers "Expires";
    proxy_cache cache_zone;
    proxy_cache_valid 200 301 302 304 5m;
    proxy_cache_use_stale error timeout invalid_header updating;
    proxy_cache_key "$scheme$host$uri$arg_lo$arg_ver$arg_lg";
    proxy_pass http://lp_api;
    proxy_connect_timeout 2;
    proxy_send_timeout 2;
    proxy_read_timeout 2;
    proxy_redirect default;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Real-IP $x_remote_addr;
    proxy_set_header Host $http_host;
    proxy_set_header Range $http_range;
    }

log设置
log_format access15 '$http_x_forward_for $request_time $upstream_response_time $upstream_cache_status';
upstream_cache_status会有如下值:
·MISS 未命中,请求被传送到后端
·HIT 缓存命中
·EXPIRED 缓存已经过期请求被传送到后端
·UPDATING 正在更新缓存,将使用旧的应答
·STALE 后端将得到过期的应答

Nginx缓存最佳实践
http://blog.text.wiki/2017/04/10/nginx-cache.html
nginx cache查看命中率
http://www.361way.com/nginx-cache/2665.html

AWS的Cloudfront没有采用GZIP的问题

问题的现象:
例如源站source.ciika.com,加速域名为ciika.com,web服务器为nginx,在直接访问源站的时候,是有gzip的,但是通过CDN之后就没有压缩了,直接原样输出了,所以问题应该出现了cloundfront回源的问题。

问题的原因:
由于cloundfront采用的是http1.0去回源,而http1.0没有携带 Accept-Encoding,这个是在http1.1才有的,所以nginx认为用户无法解压,所以直接把未压缩的内容传输给cdn,然后cdn在原样传输给用户。

解决方案:
修改nginx的配置

gzip on;
gzip_http_version 1.0;
gzip_proxied any;
gzip_types text/css application/x-javascript;
gzip_vary on;

gzip_proxied any,表示无条件的输出gzip内容给用户

参考:
http://nginx.org/en/docs/http/ngx_http_gzip_module.html#gzip_proxied
https://pelanne.com/blog/enabling-gzip-compression-your-nginx-served-cloudfront-content/

AWS Api gateway绑定自定义域名

在使用API Gateway的时候需要绑定自己的域名,我这里没有和CDN联系在一起,就需要用自己的域名去做关联。本篇文章完全是入门文章,我是今天花了一下午的时间才把这个看似简单的过程给全部串在一起,大体过程如下:

准备API

1.新建一个api,这里我不做多的描述,我直接是采用官方的宠物商店的示例做的,其中要注意的是stage在测试的时候需要写成beta,把这个写好后就直接deploy api.

绑定自定义域名

2.申请https证书
因为api gateway只支持https,官方的解释为:

问:我是否可以创建 HTTPS 端点?

答:可以,通过 Amazon API Gateway 创建的所有 API 都只公开 HTTPS 终端节点。Amazon API Gateway 不支持未加密的 (HTTP) 终端节点。默认情况下,Amazon API Gateway 将内部域分配给自动使用 Amazon API Gateway 证书的 API。如果您将 API 配置为以自定义域名运行,则可以为域提供您自己的证书。

https://aws.amazon.com/cn/api-gateway/faqs/
例如我的域名为:test.ciika.com,腾讯云刚好提供了一年免费的SSL证书
q1_ink_li
申请好后,我们会得到三个文件:1_root_bundle.crt ,2_test.ciika.com.crt ,3_test.ciika.com.key
还有一种方式是采用openssl自己去生成

3.api关联域名
这一步我花了比较多的时间,一直在报错,如图:
q2
把上面得到的内容填充到上面即可,填充关系为:
1_root_bundle.crt  ->chain
2_test.ciika.com.crt ->body
3_test.ciika.com.key ->private key
点击SAVE后,会提示

Create an Alias resource record with your DNS provider to map test.ciika.com to affafa66zkqp3.cloudfront.net
Certificate name
testciika
Distribution domain name
affafa66zkqp3.cloudfront.net

DNS留着最后一步用,先来添加api mapping
q4

4.设置DNS
在腾讯云的域名解析里面,添加cname 到步骤三里面得到的DNS affafa66zkqp3.cloudfront.net
q5

到这里为止,所以的工作都到位了,在浏览器里面访问https://test.ciika.com/abc/pets
得到了我们想要的结果

[
	{
		"id": 1,
		"type": "dog",
		"price": 249.99
	},
	{
		"id": 2,
		"type": "cat",
		"price": 124.99
	},
	{
		"id": 3,
		"type": "fish",
		"price": 0.99
	}
]