标签:CDN
建站分享COS对象存储和CI数据万象未开启CDN,但是却有CDN回源流量
发现的问题对象存储简称COS,数据万象简称CI。由于5月数据万象突然征收“CDN回源流量费”,由于先森图片请求量不大,且还是需要使用数据万象的图片处理功能,所以先森在CDN->COS的中间加了一个Nginx做反向代理,由于Nginx所在的服务器和先森的COS存储桶是同地域的,所以服务器到COS的流量是内网,因此讲道理COS和CI都不会产生CDN回源流量了。但是,先森过了几天又来看数据万象控制台,发现每天还是有产生CDN回源流量,先森这波就无语了,明明都没用CDN了,怎么还会有CDN回源流量呢,这不是无中生有么。数据万象控制台问题原因定位经过排查确认,是由于先森的Nginx直接透传了CDN的回源请求,导致COS和CI判定流量是来自CDN回源。。。先森在服务器上进行抓包确认。同一个图片,CDN回源到CVM服务器:抓包:CDN回源到CVM服务器CVM回源到COS:抓包:CVM回源到COS可以看到,CDN回源到CVM比较有特殊性的请求头是以下两个,在CVM请求到COS时也是带着的: X-NWS-LOG-UUID: 630013543448005765 X-Tencent-Ua: Qcloud那么,就要想办法把这两个请求头去掉,不让其透传。去除Nginx请求头先森百度了一下,Nginx内置的模块中没有删除指定请求头的,只能编译增加headers-more-nginx-module模块。先森图省事,服务器安装了宝塔,Nginx是通过宝塔安装的。看了一下,宝塔安装的Nginx不像Redis等软件,可以在网页上动态添加支持模块,只能命令行编译添加模块。当然编译之前需要看一下宝塔的Nginx会不会已经很好心的帮忙编译了headers-more-nginx-module。查看Nginx已经安装的模块 ./sbin/nginx -V nginx version: nginx/1.22.0 built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) built with OpenSSL 1.1.1o 3 May 2022 TLS SNI support enabled configure arguments: --user=www --group=www --prefix=/www/server/nginx --add-module=/www/server/nginx/src/ngx_devel_kit --add-module=/www/server/nginx/src/lua_nginx_module --add-module=/www/server/nginx/src/ngx_cache_purge --add-module=/www/server/nginx/src/nginx-sticky-module --with-openssl=/www/server/nginx/src/openssl --with-pcre=pcre-8.43 --with-http_v2_module --with-stream --with-stream_ssl_module --with-stream_ssl_preread_module --with-http_stub_status_module --with-http_ssl_module --with-http_image_filter_module --with-http_gzip_static_module --with-http_gunzip_module --with-ipv6 --with-http_sub_module --with-http_flv_module --with-http_addition_module --with-http_realip_module --with-http_mp4_module --with-ld-opt=-Wl,-E --with-cc-opt=-Wno-error --with-ld-opt=-ljemalloc --with-http_dav_module --add-module=/www/server/nginx/src/nginx-dav-ext-module肉眼可见的,并没有headers-more-nginx-module模块,只能重新编译一下了。由于宝塔编译的Nginx没有留configure文件,所以先森参考这篇文章:宝塔面板安装的Nginx(已安装)如何添加echo-nginx-module模块,操作了一下编译。其中,有一些点需要注意一下。1、模块的下载地址,下载后解压得到的目录,就是编译时指定的目录: wget https://github.com/openresty/headers-more-nginx-module/archive/refs/tags/v0.33.tar.gz tar -zxvf v0.33.tar.gz -C /www/server/module/ ls /www/server/module/headers-more-nginx-module-0.332、下载的模块目录不要放在/www/server/nginx目录下,使用先森参考的这个方法宝塔在更新Nginx时会清空该目录;修改反向代理配置文件进入宝塔的网站配置页,找到反向代理的配置文件,增加想要去除的请求头即可。 more_clear_input_headers "X-Tencent-Ua"; more_clear_input_headers "X-NWS-LOG-UUID";修改反向代理配置重新抓包确认请求头没有透传修改好了之后,重新抓个包,看看请求头还有没有透传。CDN回源到CVM服务器,可以看到这两个请求头还是在的(肯定在,先森又没删)。CDN回源到CVM然后再看CVM服务器访问COS的请求头,指定清除的两个请求头已经没有了。先森只是刚改好,由于数据万象的控制台对于“CDN回源流量”的监控粒度是1天,所以起码要明天才能看到效果,希望有效。
建站分享CDN回源到COS突然产生数据万象的CDN回源流量
存在的问题在这六一儿童节的欢乐佳节,腾讯云又给先森送了一波小礼,上一次还是先森毕业的时候,腾讯云恭喜先森毕业,并收走了先森1元购买服务器的资格。。。大清早的,腾讯云邮件、短信通知先森腾讯云账号欠费停服了,先森表示一脸懵逼。登录腾讯云费用中心,发现是数据万象产生了CDN回源流量,这更是让先森感到懵逼。腾讯云账号欠费明细先森自2020年就将对象存储从七牛转到腾讯云COS了,在此之间从未发生过费用,之前先森还炫耀过:网站http转为https之始,从七牛到腾讯云突然产生的CDN回源流量让先森真的很奇怪,再次确认,COS是有CDN回源流量包的,先森的CDN源站也是COS域名而非数据万象的域名。COS的CDN回源流量包问题原因先森联系售后在线支持,经过确认得知,只要CDN回源时带了图片处理参数,那么就算是CDN回源到数据万象,啊这。。。先森就很无语售后的答复先森的解决办法数据万象产品的策略已经这样了,先森也没有办法改变,先森去联系售后,也不是为那6分钱讨回公道的,及时止损才是王道。针对这种情况,先森想到了两个解决方案:1、CDN继续使用腾讯云的,源站改为七牛对象存储或CDN域名;2、使用同地域的服务器做一个反向代理,CDN源站改为这个服务器,服务器通过内网访问对象存储,这样就不会产生对象存储和数据万象的流量费用,也就不存在CDN回源流量费了。先森选择了第二种方案,第一种方案可以用来做CDN的备用源站,避免自建反向代理挂了的话导致网站访问受到影响。第二种方案配置起来也简单,宝塔上增加一个站点,设置反向代理,目标URL和发送域名都填上COS的域名即可:宝塔的反向代理配置注意事项需要注意的是,使用的CVM服务器一定要与COS所属地域一致,且CVM的dns服务器保持腾讯云默认DNS,否则不会解析到内网。配置反向代理前,可以在服务器内解析验证一下,解析出来应该是一个169.254.x.x的IP:dig确认内网解析不打算再使用腾讯云数据万象的图片处理功能?那么,如果希望继续使用对象存储COS,但是又不希望无意间使用到数据万象该怎么办呢?经过确认,可以在数据万象的控制台操作对应存储桶“解绑”,解绑后COS桶就无法调用数据万象的能力了。数据万象解绑COS桶
建站分享网站事故,网站将您重定向的次数过多
现在工作、生活需要关注的事情越来越多了,对博客的关注度是越来越少了,上一次发文章已经是去年的事情了。前段时间服务器被人通过宝塔漏洞登录成功,腾讯云告警了,先森知道被人攻破的服务器,不重装的话是很难清理干净的,所以简单备份了一下相关数据就重装了,结果还出了点小问题,一个月都没发现。在重装的一个多月后,先森上自己博客查点资料,结果发现网站打开不了,看报错是网站将您重定向的次数过多。网站将您重定向的次数过多(为了演示,先森临时开了一个测试网站test.capjsj.cn)问题原因作为一枚资深腾讯云售后工程师,这个小问题当然是看一眼就知道原因了。去年,先森将网站从http转为了https访问,先森前端使用的CDN,网站如果从http访问,肯定得跳转到https的,但是这个问题不是CDN跳转的问题。先森当时配置的回源方式是http回源,然后网站在宝塔中配置的是http访问,这没问题,但问题就出在重装服务器之后,先森将宝塔中网站也配置成https访问了,还手贱的开启了强制https访问:宝塔配置强制HTTPS客户端访问CDN域名,使用HTTPS进行访问,然后CDN使用HTTP进行回源,然后源站开启了强制访问HTTPS,源站会返回CDN一个301跳转到https的请求,然后客户端又开始https访问,不停的拿到301请求,导致死循环。解决办法这问题解决起来也非常简单,有两种方法。第一种是把宝塔里的强制HTTPS关掉,第二种是在CDN的回源配置中,配置为HTTPS回源或者协议跟随。修改CDN回源协议 总结这个问题相当简单,但是在我的腾讯云运维生涯中,还是有很多客户遇到反馈过。先森服务器是重装的,由于舍不得钱没有做快照,如果各位有预算的话,服务器建议还是定时做下快照。有快照的话,先森就不用手动再去做各种配置了。
系统运维CDN防盗链遇到的一个坑
本着安全的考虑,先森在腾讯云的CDN配置里开启了防盗链的配置,结果先森发现这里面有个小坑,竟然禁止了搜索引擎。发现与排查先森最近有开始关注起来网站了,之前先森对网站是一个活着即可的态度的,所以CDN的缓存时间配置的比较长,先森想着缓存命中率应该很高才对,结果实际上很低,所以先森开始寻找命中率低的原因。命中率低可能的原因首先,先了解一下可能是哪些原因导致命中率低。先森看了一下上面的原因,最大的可能就是状态码4XX和5XX的情况了。通过CDN控制台的运营报表,先森看到网站的404和403的情况挺多的,5XX的情况倒是很少:网站4xx情况然后先森就很疑惑了,这个404先森还理解,这个是由于很多人拿先森网站练手,疯狂访问不存在的zip或rar压缩包,或者asp网页等,造成大量404,先森今日也是在分享访问次数多的重复IP,量大的就加到CDN的IP黑名单里面,一次两次的就懒得管了。不过这个403先森就很不解了,访问中出现403的IP也不全是先森加到IP黑名单中的呢。日志分析403情况而且访问的链接也是很正常的链接,然后单独过其中一个IP看了一下:单独IP分析然后看到5次请求都是403,来源都是百度,先森先尝试直接打开这个网页,发现访问是正常的。然后再通过访问来源百度的链接打开,这个链接确实会跳转到先森的网页,发现竟然403了。百度跳转403果断F12打开审查元素,仅看响应头没有看出什么端倪,然后先森就开始思考,CDN的配置中,还有哪里会出现403的响应。这种必然是安全方面的配置,且先森开启的也不多,仔细想一下就想到应该是防盗链配置了。然后看了一下请求头,果然如此:请求头中的referer先森的referer防盗链里面并没有配置百度的域名,所以出现了这种情况,这个是先森配置的时候没有考虑到的。解决起来也简单,两个办法,一个是防盗链中增加百度等域名,一个是关闭防盗链白名单。CDN防盗链配置先森选择了最简单的方式,直接关闭了防盗链,相信也没有哪位大佬来盗链先森的网站。如果实在有的话,就配置相关黑名单吧。如果每个搜索引擎都去配置到白名单,总还是会有疏漏,所以还是关掉比较省事。总结配置防盗链,竟然让搜索引擎来源中了招,这个让先森有点始料未及,所以网站的情况还是得多关注一下,如果先森又是放个大半年再来关注,怕是网站已经在搜索引擎那里零分了。
WordPress技巧网站从http转为https折腾记录
先森之前先发了一篇博文,讲述了一些想从http转为https做的一些准备:网站http转为https之始,从七牛到腾讯云前进的道路从来都不是一帆风顺的,先森在切换的过程中也是遇到了一些问题,这里简单的记录一下历程。七牛转腾讯云七牛令先森最喜爱的功能就是图片的处理功能了,现在是腾讯云的对象存储COS也支持直接图片处理,所以先森才开始打算从http转为https。针对七牛的图片处理,先森以前还是写过几篇博文的:WordPress百度UEditor编辑器自动添加七牛云储存裁剪代码将WordPress历史文章中所有图片加上七牛裁剪水印代码七牛图片处理样式的正确使用方式当然,当时的用法比较简单粗暴,直接用了一大段的图片处理参数,而正确的方法应该是将固定的处理方法保存为处理样式,直接在图片后面调用图片处理样式,这个先森也在上面的最后一篇博客中写到了。先森使用图片处理,最主要的用途还是加速网站打开速度。将不同位置的图片缩小至合适的大小,让图片的体积尽可能的减小,以实现加快网站访问速度。先森最喜欢的一点,还是文章中的图片,结合灯箱插件,让图片在未点击时呈现缩放并降低图片质量的状态,点击后显示原始大小及质量。这么好的功能先森当然不想放弃,先森网站的各种缩略图都是不同的大小,所以有不同的样式。本以为从七牛的图片处理换到腾讯云的图片处理,相关规则还得自己研究半天才能实现同样的效果,结果图片处理的规则竟然非常兼容。COS图片处理规则除了需要添加水印的规则,其他的规则直接将七牛的复制过来就可以直接用了,简直方便的一批。COS新增样式时,添加水印图片竟然只能上传图片,而不能从存储桶里直接选择,这一点有些体验不佳。而自己通过自定义规则去添加水印图片的话,又会比较麻烦:使用自定义参数添加水印图片需要满足3个条件不过研究一下还是可以完成操作,总的来说,这个切换过程还是非常满意的。自适应http和https先森前面的文章也写到过,为了避免切换到https有问题,先森切换的时候是没有开启强制跳转到https的,所以这里就需要做到http和https的兼容。先森想到的兼容方式就是将网页中的‘http://’换成‘//’,这样就会根据访问的协议自动显示相应的协议。要实现也很简单,先森下面这篇博客中讲到了“WordPress七牛CDN代码版”:七牛图片处理样式的正确使用方式先森这里把这个代码改吧改吧就能实现https的兼容了。//WordPress七牛CDN代码版function QiNiuCDN(){ function Rewrite_URI($html){ /* 前面是需要用到七牛的域名,后面是需要加速的静态文件类型,使用分隔符 | 隔开即可 */ /* 这里先森小改了一下,兼容https */ $pattern ='/http[s]{0,1}:\/\/(www\.|)capjsj\.cn\/(wp-|ueditor|avatar)([^"\']*?)\.(jpg|js|css|gif|png|jpeg|ico|cur)/i'; /* 七牛CDN空间地址,请自行替换成实际空间地址*/ /* 先森这里又换成腾讯云COS的地址了 */ $replacement = '//cos.capjsj.cn/$2$3.$4'; $html = preg_replace($pattern, $replacement,$html); /* 增加了一次替换,把http://替换为// */ $html = preg_replace('/http:\/\/www.capjsj.cn/i', '//www.capjsj.cn',$html); return $html; } if(!is_admin()){ ob_start("Rewrite_URI"); }}add_action('init', 'QiNiuCDN');这个时候需要注意,WordPress后台登录的时候,需要使用http,因为在设置-常规处的WordPress地址与站点地址还未修改,为了http与https的兼容,所以当时也并未修改。但若要修改,这里还有个坑。全站HTTPS先森经过一段时间的测试,发现https没有什么问题,所以就打算将网站开启HTTP到HTTPS的强制跳转,并且把后台配置中的站点地址也改成HTTPS,但是先森修改后,竟然遇到了后台地址无限跳转。HTTPS无限302跳转经过一番搜索,发现是需要在WordPress网站根目录中的wp-config.php中添加配置进行解决:/* 解决https无限跳转*/$_SERVER['HTTPS'] = 'on';define('FORCE_SSL_LOGIN', true);define('FORCE_SSL_ADMIN', true);添加在文件开头处即可,药到病除。CDN缓存命中率低先森闲来无事,跑去17ce测试了一下网站的GET速度,结果大出先森预料,竟然全国通红(忘了截图)。先森觉得很奇怪,先森这网站这么久了没更新了,按理说应该访问到的都是缓存才对啊,然后先森进行了排查。先森就从首页排查起,先森在非放置本站的服务器上curl首页,结果发现经常是 X-Cache-Lookup: Cache Miss,但是连着刷两次就会变成Cache Hit,但是再过几秒curl又变成Cache Miss了,这就有点奇怪了。仔细看了一下响应头,结果先森发现 Cache-Control: must-revalidate, max-age=3,这就表示缓存3秒啊,怪不得连着刷能命中缓存,接下来就要看这个响应头是怎么配置的了。不过讲道理,腾讯云的CDN判定是否命中缓存的规则是看X-Cache-Lookup是否为Hit From MemCache或Hit From Disktank,直接显示Cache Hit和Cache Miss是很奇怪的。X-Cache-Lookup:Hit From MemCache 表示命中 CDN 节点的内存。X-Cache-Lookup:Hit From Disktank 表示命中 CDN 节点的磁盘。不过先森也去查了一下,Cache Hit也是正常命中缓存了,也不需要过多的去纠结。这个仅缓存3秒的响应头,先森自己记得是没有配置的,可能比较容易出问题的可能是WordPress中使用的缓存插件。先森使用的缓存插件是WP Super Cache,所以首先就是怀疑这货。百度大法好,果然是这货影响的。默认情况下,WP Super Cache 返回的 Cache Control Header 固定为: cache-control: max-age=3, must-revalidate ,不管你在插件设置中设置的缓存超时时间是多久。修改起来也简单,只要在WordPress根目录的wp-config.php增加配置即可:define('WPSC_CACHE_CONTROL_HEADER','max-age=3600, must-revalidate');参考:WP SUPER CACHE 缓存插件但是,如果CDN的缓存也是继承源站的响应头,那先森在腾讯云CDN的缓存配置岂不是没有用了?所以还是得研究一下什么情况下,CDN会继承源站的配置。腾讯云官方文档对高级缓存配置的说明经过一番查阅腾讯云官方文档,发现是开启高级缓存配置时,CDN会对比源站响应头中的max-age值。先森看了一下自己CDN的配置,果然是开启了高级缓存配置的,赶紧关闭:关闭高级缓存配置这个配置估计是为了迎合一些对自定义配置要求较高的用户,先森这种小站就没必要开启了。CDN对no-cache或者no-store不缓存需要注意的一点是,默认情况下,CDN也不会对no-cache或者no-store的资源进行缓存,所以如果有遇到始终无法缓存的情况,可以检查一下cache-control是否配置了禁止缓存。先森最终是即修改了WP Super Cache的配置,将max-age改为了3600,即1个小时;CDN侧是关闭了高级缓存配置。至于为什么关闭了高级缓存配置的情况下,还要修改插件的缓存配置,那是因为max-age还会影响到客户端浏览器的缓存配置,3秒太短了,所以还是修改一下比较好。修改之后,过了一段时间,先森再进入17ce进行GET测试,测试的结果就能让先森接受了:17ce测速总结先森在网站开启HTTPS中,可能还有一些比较小的坑,先森随手就解决了,这里就没有记录了。网站加了CDN后,访客具体的访问速度先森实际上也不得而知,因为先森自己打开网站觉得还是很快的,结果用17ce一测,全红,这个17ce的数据也不知道与实际情况是否匹配。如果有访问比较慢的,还希望能够留言告诉先森,您的地域与具体访问的URL。
WordPress技巧网站http转为https之始,从七牛到腾讯云
最近先森还是重拾了一点大学期间的激情,对网站又上心了一点。周围的网站看着都将http换成了https,先森也想着动一动了。目前是已经完全换为https有一段时间了,先森也记录一下切换过程中折腾的一些情况。首先,七牛七牛,先森最早开始使用的CDN与对象存储。当然,当时并不清楚这些概念,不过依然非常感谢七牛这些年来的陪伴。先森最早一篇关于七牛的文章是2015年9月初写的,先森的域名是同年6月份购买的。最早的记录:WordPress使用七牛CDN导致ajax评论报错{“error”:”get from image source failed: E405″}当初先森还不愿意使用七牛,因为插件没什么作用,但后面正确使用后的感觉是真香,这一香,就香了五年。七牛对象存储的免费额度七牛免费10G的存储空间,以及10G的下载流量,还有图片处理的免费额度,让当时囊中羞涩(现在也是)的先森万分欣喜。当时先森使用的还是万网的免费虚拟主机,一个月只有10G的流量,刚开始没有使用七牛的时候,各种折腾,然后各种跑满。使用七牛,让图片、js文件等静态文件都走七牛CDN后,问题得到有效解决。不过要使用https了,还是得跟七牛暂时告一段落了。七牛CDN的免费额度七牛的对象存储必须搭配CDN进行使用,否则无法外网访问。而七牛的CDN只有http请求有免费额度,https是必须收费的。虽然非常感谢七牛的陪伴,但是有白嫖的机会又何必花钱呢?然后,腾讯云先森一直不愿意换HTTPS的原因就是因为七牛,尤其是七牛的图片处理,可以在请求图片时对图片进行各种压缩、裁剪、加水印等操作,对网站加速访问很有益处。但先森毕竟是一名腾讯云公有云售后运维,对自家产品了解还是很深的。在七牛使用了两个产品,一个是对象存储,一个是CDN。而要换到腾讯云,就得观察好对应的产品。以前知道腾讯云也有图片处理的相关产品,叫做万象优图,现在改名叫做数据万象,不仅仅做图片处理了。但是一直没有去深入了解,也觉得既要使用腾讯云对象存储,还要使用万象优图,很麻烦,不像七牛那么方便:对象存储的图片,加上参数就能做图片处理。但是今年3月,腾讯云对象存储做出了改变,当时发了邮件:对象存储发布图片处理功能当时先森对网站是放任不管的,对此也没有在意。不过最近腾讯云又发了一次短信通知,先森又去研究了一下。对象存储COS先森目前对网站本来就不是很重视,要切换使用一定是在有免费额度的基础上。这里就需要注意的是,腾讯云的对象存储COS在去年9月份是对免费额度进行了调整的,在2019年1月22日之前开通使用对象存储的老用户继续每月享有之前的免费额度,之后开通的,就只有6个月的免费额度了。但是老用户还得注意,看自己有没有收到过以下邮件:COS免费额度变更标明了【不受此次变更影响】的用户才能继续享受每月免费额度,如果有什么疑问,可以在腾讯云官网联系在线客服或提交工单。腾讯云COS的免费额度还是比较给力,存储50G,流量10G,请求次数100万次。先森在使用时,一般都是配合CDN进行使用,所以这里要关注的是CDN回源流量。先森这边刚好有个账号还享有免费额度,所以具备七牛迁移腾讯云的基本条件。然后继续往下看。腾讯云的对象存储简称COS,后面都直接用COS了。数据万象CICOS的图片处理功能,使用的是数据万象的功能,所以还得看数据万象有没有免费额度。在数据万象的文档中可以看到,很多操作都是有免费额度的:数据万象免费额度这里先森重点关注的是基础图片处理和CDN回源流量,这两项是先森用的上的。基础图片处理10TB/月,七牛是20TB/月,对于先森来说完全够了,先森11月5号开始使用,截止目前才用不到2GB,说来也是惭愧。CDN回源流量10GB/月,对先森来说也是完全够用了。由于是结合COS来使用的,图片不添加处理参数时,是不会回源到数据万象的,所以这个流量先森目前用的特别少,才200MB+。需要注意的是外网出流量,只要你不直接使用数据万象CI默认域名进行访问,仅使用CDN->COS->CI的方式访问的话,是不会产生的。数据万象默认域名格式为存储桶名-账号Appid.piccd.myqcloud.com,尽量还是使用自己的域名通过CDN访问吧。内容分发网络CDN对象存储和数据万象都有免费额度了,那么再来看看CDN。CDN不像对象存储和数据万象,这样费用那样费用,简单直接,就一个流量费用。不过CDN的免费额度按照官方文档来说,个人用户于官网开通 CDN 当天可获赠共120GB免费境内流量包。分6个月生效,每月生效20GB。其他就没有更多说明了,不过目前看来,只要接入了CDN,每个月还是会有10GB的赠送流量包,对先森来说够用了,使用前可以在控制台看下自己是否有赠送流量包:CDN免费流量包另外一点,SSL证书要从http切换为https,证书是肯定少不了的。想要安全,肯定不可能使用自颁发的证书,不过免费的证书也还是挺多的。先森使用的SSL证书是在腾讯云上直接免费申请的。腾讯云申请的免费证书是由亚洲诚信提供的,实际上也是DigiCert的免费DV证书。想比于Let's Encrypt证书的3个月一换,先森还是喜欢一年一换的。虽然Let's Encrypt证书可以跑脚本进行替换,但是从宝塔上的一些体验来看,这个自动替换还是有点坑的。先森不想过多的去修改源站web服务器上的配置,所以SSL证书是直接部署到CDN上的,使用http的方式进行回源。刚开始切换https的时候,先森担心https会出现问题,所以没有开启http到https的强制跳转,将证书部署在CDN上面,切换起来比较方便。当然,在切换的过程中,还是不免的遇到一些坑,为了避免篇幅过长,先森这边后面再说。后面的记录:网站从http转为https折腾记录
经验杂笔慎用百度云观测 竟把网站拖垮
先森的网站还是放在阿里云免费云虚拟主机,每个月被关停之后,只能启动三次。先森上一次被关停是7月份的事情,没想到昨天凌晨,噩梦又来袭。早上先森上班之后,抽空看了一下网站的日志。因为阿里云的提示短信是凌晨三点四十多发的短信,所以先森重点关注这个时间段的,然后就发现了罪魁祸首,这篇文章的主角——百度云观测。坑爹的百度云观测在日志中,我发现了大量的请求,全是User-Agent:Baidu-YunGuanCe-ScanBot(ce.baidu.com),而且访问的还都是/wp-comments-post.php和/wp-admin/admin-ajax.php这些会接收数据,查询、修改数据库的php文件,这样一来对网站的压力就非常的大了。来自百度云观测的大量请求这种情况,先森赶紧去百度云观测把网站监控关闭,百度云观测的骚操作太恐怖了。关闭百度云观测后续先森在百度云观测找到这样的一段话,先森感觉心中一万只。。。。网站初始化包含多个分析过程,一般需要5~10分钟。 网站初始化时,我们会对你的网站进行全方位安全体检。初始化这段时间内,可能会向你的网站发送一定攻击探测请求,以发现安全漏洞。 一般情况下,正常网站不会因为安全体检受到任何影响。后来,昨天下午先森的网站又被关停了一次,这一次,不是百度云观测的锅了,先森已经关了。这次,是有人在拿先森网站练手,搞DDOS,先森看日志,发现大量的125.39.239.*网段的请求。因为网站放在百度云CDN,免费版又不能设置黑白名单,所以先森只把防守放在了.htaccess文件里面,但是先森发现,放在里面并无卵用,有了CDN,该访问还是能访问。所以先森还是把网站CDN都解析到腾讯云CDN。腾讯云CDN对移动宽带的支持貌似不太友好,但是好在是能够配置黑白名单,有这点就够了。
WordPress技巧CDN后用Ajax动态提交、显示文章阅读量,cookies避免重复刷新
上篇文章解决了WordPress加入CDN后“非插件浏览次数统计”浏览次数不刷新问题,同时留下了两个未解决的问题:1.按F5可无限制刷新文章访问量,并影响数据库效率;2.只解决了后台不更新问题,前台显示还是得等CDN刷新后才能更新。那么这篇文章就是为了解决以上两个问题。问题分析第一个问题,先森想到的解决方法是用JS代码创建cookies,如果cookies存在就不在更新后台的统计量。第二个问题,直接让ajax获取后台的访问量,修改前台显示的访问量就行了。一开始,先森配置的让ajax多传一个参数,是判断cookies是否存在的,存在为1,不存在为0。若cookies不存在,则后台访问量统计就+1,并返回数据库中的浏览量并+1。若cookies存在,则后台不增加访问数量,直接返回数据库中的浏览量并+1,如此访客刷新也不会增加访问量了。但是这样还是存在会在后台查询数据的问题,查询多了对数据库也是一种负担。先森之前没有意识到这个问题,结果还是晚上睡觉前反思发现了,且也琢磨除了一个更好的解决方法。直接在JavaScript代码中加判断,如果cookies已存在,则直接不向后端服务器发数据。这样一来,前端再怎么刷新,也停留在CDN的层面上。那么要实现这种效果,就需要先实现不向后端服务器发送数据,也能获取到当前文章的访问量。解决方法很简单,第一次获取访问量时,将后端服务器返回的访问量直接写入cookies,下次刷新时,直接从cookies中读取访问量。另外,还有一个地方需要解释一下,cookies的过期时间。如果cookies时间太长了的话,那么未免还是会损失一些访问量,所以先森就没有设置cookies的过期时间,保持默认。cookies的默认过期为关闭浏览器,先森觉得,这样一来还是比较合理的。同时,一个访客,可能并不会只打开本站一篇文章就关闭,打开多篇文章时,每篇文章的访问量是不一样的,需要从cookies中获取的话,cookies的名称就必须不一样。不然访问打开其他文章,看到了访问量都是同一个数值。解决方法就是,已“固定值+文章ID”的方式,确定cookies名称的唯一。效果实现上一篇文章中,先森是模仿通用的评论ajax提交的处理方式,自建了一个类似的php。但这样可能有点不安全,也有点麻烦,所以先森还是研究着将php代码部分放进了主题的functions.php。首先还是在footer.php中添加ajax的代码,注意需要将前台显示访问量的标签ID或class名称改成自己的。<script type= "text/javascript" > function GetCookie(sName) { var arr = document.cookie.match(new RegExp("(^| )"+sName+"=([^;]*)(;|$)")); if(arr !=null){return unescape(arr[2])}; return null;}var postviews_cook=GetCookie("postviews<?php the_ID();?>"); if ( postviews_cook == null ){$.ajax({ type:'POST', url: "<?php echo admin_url('admin-ajax.php');?>" , data:"postviews_id=<?php the_ID();?>&action=postviews",cache:false,success: function(postviews_count){ $("#views").text('阅读:' + postviews_count + ' 次');document.cookie="postviews<?php the_ID();?>=" + postviews_count;} }); } else{$("#views").text('阅读:' + postviews_cook + ' 次');}; </script><?php endif ; ?>然后直接在自己主题的functions.php中添加下面的代码:/** 缓存时更新浏览量-有缓存* //www.capjsj.cn/ajax_cookies_views.html*/function postviews_cache(){ if( empty( $_POST['postviews_id'] ) ) return; $post_ID = $_POST['postviews_id']; if( $post_ID > 0 ) { $post_views = (int)get_post_meta($post_ID, 'views', true);/*if( !defined( 'WP_CACHE' ) || !WP_CACHE ){ 以前的错误代码*/if( defined( 'WP_CACHE' ) && WP_CACHE ){ //如果wp-config.php开启缓存 update_post_meta($post_ID, 'views', ( $post_views + 1 ));} echo ( $post_views + 1 ); exit(); }}add_action( 'wp_ajax_nopriv_postviews', 'postviews_cache' );add_action( 'wp_ajax_postviews', 'postviews_cache' );2018年06月07日更新:感谢网友@鱼鱼 在评论区指出的BUG,以前写上面的代码的时候参考了wp-postviews插件wp-postviews.php里面的代码,结果学艺不精,只看了上半截,忽略了下半截。错误的代码竟然用了近1年的时间没发现,还发布在这里误人子弟,实在羞愧。上面的代码中,错误的代码依然留存着,只是注释了,修改的方法有两种,第一种是上面那样,第二种则是将10-12行的if段改为下方模式(这种就是wp-postviews插件的写法):if( defined( 'WP_CACHE' ) && WP_CACHE ) //如果wp-config.php没有开启缓存 return; //退出(中止函数的运行) update_post_meta($post_ID, 'views', ( $post_views + 1 ));注意,如果网站的WordPress只加入了CDN,没有使用缓存插件的话,需要将上面代码改成下面的,也就是删除开启缓存判断:/** 缓存时更新浏览量-无缓存* //www.capjsj.cn/ajax_cookies_views.html*/function postviews_cache(){ if( empty( $_POST['postviews_id'] ) ) return; $post_ID = $_POST['postviews_id']; if( $post_ID > 0 ) { $post_views = (int)get_post_meta($post_ID, 'views', true); update_post_meta($post_ID, 'views', ( $post_views + 1 )); echo ( $post_views + 1 ); exit(); }}如果想使用有缓存的版本,想要开启网站缓存,可以选择安装缓存插件,或者直接在网站根目录的wp-config.php中,加入下面这行代码:define('WP_CACHE', true);如果网站没有加入CDN,也没有使用缓存插件,那么有两个选项:1、Ctrl + D 保存本页到书签,待文章变成静态页面后再拿出来看看;2、Ctrl + W 关闭本页,因为除非你要研究代码,本页对你没有什么价值,看看更多该看的吧。总结对于本文的解决方案有什么意见和建议,希望能够在下方评论栏中提出来,先森觉得还有能够改进的地方,但一人之力实在有些相形见绌。ajax是个很实用的东西,可能还有更多可以使用的地方,先森也得好好想想。
WordPress技巧解决WordPress加入CDN后“非插件浏览次数统计”浏览次数不刷新问题
不知道多少人和先森一样,在最初接触wordpress的时候,被网上的各类教程灌输了“能用代码版,就不用插件”的概念。先森就本着这个概念,在文章的访问量的时候,先森就找的代码版。网上提供的代码版浏览次数统计功能的文章,名称都差不多,类似“WordPress非插件添加文章浏览次数统计功能”这种比比皆是。先森应该是在wordpress大学看到的教程,关于教程先森就不再赘述了。本文主要解决的是,开启CDN后,用这种代码版访问量统计的方式浏览次数不再刷新的问题,如果想结合着来使用的话,统计代码部分可以去wordpress大学看《WordPress非插件添加文章浏览次数统计功能》这篇文章。浏览次数问题分析先森其实很早就意识到,开启CDN后,其实浏览量不是不刷新,而是只在首次缓存的时候才会增加一次。因为只有第一次访问的时候才会执行php,缓存后就直接访问的html了,所以就不会增加统计了。所以解决问题的方式,是让html也能统计到浏览次数,先森认知中的方法就只有一个:ajax。然而当初先森虽然知道问题原因,知道解决方式,但奈何先森代码能力不强,当时没能解决。先森始终认为,一个问题如果死活解决不了,那么就先放放,过段时间再反顾可能就会发现,这个问题根本就不是事。当然,这个时间可能就有点久了,起码就ajax这个问题,先森等了一两年。。。。先森想到的用ajax更新浏览次数的方法就是,使用ajax提交文章的ID给后方的php,后方的php接收到文章ID后,将该文章的浏览次数+1。效果实现先森研究了一晚上,发现要解决还是挺简单的。又是研究几小时,分享几分钟,心塞。首先,在footer.php中添加ajax的代码,注意url的地址要改为自己的php路径:<?php if (is_singular()) : ?> <!-- ajax post view --> <!-- ajax post view --> <script type= "text/javascript" >$.ajax({ type:'POST', url: "//www.capjsj.cn/wp-content/themes/*/*.php" , /*此处需要修改为自己的php路径*/data: { "postviews_id" : "<?php the_ID();?>" } }); </script><?php endif ; ?>接收数据的php代码很简单,参考了评论的comments-ajax.php的头部,禁止直接访问,然后加上了几行更新浏览量的代码。将下面内容保存到一个php文件中,放入自己的wordpress主题里面,将该php的访问链接加入到上面的url中:<?php//禁止直接访问本phpif ( 'POST' != $_SERVER['REQUEST_METHOD'] ) { header('Allow: POST'); header('HTTP/1.1 405 Method Not Allowed'); header('Content-Type: text/plain'); exit;}require( dirname(__FILE__) . '/../../../wp-load.php' );nocache_headers();$post_ID = $_POST['postviews_id'];$post_views = (int)get_post_meta($post_ID, 'views', true);update_post_meta($post_ID, 'views', ($post_views+1));?>如此一来,即使加入了CDN,文章页面变成了静态页面,后台也会更新访问次数了。总结这样仅仅是解决了文章页面被缓存后,浏览次数无法被统计到的问题,但是还并不完善。上面的功能实现之后,你会发现,每一次刷新浏览次数都会加一,如果有人一直按着F5,那么增加的浏览次数就有点恐怖了。这样还会增加服务器的负担,像先森这种把网站放在阿里云虚拟主机的,若负载过量还会直接关停,被人这样搞的关机先森就哭了。所以,下篇文章先森会分享使用cookies来限制访问次数无限增加的问题。另外,除了访问量持续增加的问题,还有一个地方可以优化。既然ajax能够异步提交数据,那么能不能动态的修改文章中的浏览次数呢?答案是肯定的,先森也会在下一篇文章中更新。关于上面的问题,请查看下一篇文章:CDN后用Ajax动态提交、显示文章阅读量,cookies避免重复刷新
WordPress技巧WordPress让管理员在前台匿名,避免CDN缓存
自从用上CDN,需要关注的前台页面的问题就更多了,因为要避免一些不该被CDN缓存的内容被缓存,导致访客访问到不该看到的内容,影响使用体验。最近,先森发现曾解决过的问题故态复萌。用了CDN之后比较突出的问题,就是如果一篇文章如果先森登录之后再去访问,其他访客访问的时候,会显示“内容管理”、“登出”、评论框会显示先森的头像等问题。这个问题其实之前已经处理过了,但是先森wordpress升级之后,发现原本通过WP Super Cache设置的“不要为已知用户缓存”和“让已知用户匿名使他们浏览的内容是缓存文件”竟然失效了。查看了下WP Super Cache的版本,发现四周前才更新,并且提示与当前WordPres版本兼容,先森也确定选项已经勾选,但就是不生效,所以就很心塞。发现问题,处理问题。先森冒着英语超烂的风险,去了WP Super Cache的插件页面,看了一圈问题讨论,就是没发现有人提这个BUG的,在官方找解决方案的道路失败了。也不知道新的版本什么时候发布,发布会不会包含解决这个问题,所以先森只能又冒着php一知半解的风险来写代码了。解题思路解决方式先森觉得有两种,一个是去把自己的主题中的前台中管理员登录后才会显示的代码给删掉,另一种就是让管理员在前台匿名,被认为没有登录。第一种方案,先森觉得有点费时费力。当初主题的代码是自己一行一行的写的,现在让自己去删,内心表示很痛苦啊(心中憧憬着哪天要是不用CDN了...)。所以先森还是想实现第二种方案。经过研究自己的主题,先森发现,会显示管理员才能看到的东西,大多使用了这样的一种套路:<?php if (is_user_logged_in()){ '我是管理员'} ?>都用的is_user_logged_in()这个函数来判断用户是否登录,所以先森就想,让这个函数返回“用户没有登录”岂不是就可以了?is_user_logged_in()函数介绍:is_user_logged_in()函数位于wp-includes/pluggable.php函数参数:该函数不接受任何参数。返回值:已登陆返回True,否则返回False。先森在函数所在位置,找到了这个函数的代码:if ( !function_exists('is_user_logged_in') ) :/** * Checks if the current visitor is a logged in user. * * @since 2.0.0 * * @return bool True if user is logged in, false if not logged in. */function is_user_logged_in() { $user = wp_get_current_user(); return $user->exists();}endif;先森把上面的return内容改成了如下内容:if(!is_admin()){ return false;}else{return $user->exists();}这样之后,只要不是后台,就会返回false,这样前台就会得到管理员没有登录。先森发现使用了is_user_logged_in()函数的位置都已经不会在登录的情况下显示了,但是还有两个地方例外。第一个地方是文章页面上的“编辑”按钮,另一个就是评论的头像了。通过查看代码,先森发现编辑按钮用的是edit_post_link()函数:edit_post_link('编辑', ' | ', '');函数说明:若用户已登录且具有编辑文章的权限,该标签显示一个可编辑当前文章的链接。该标签必须用在主循环(loop)中。这个函数就没有使用is_user_logged_in()函数了,所以通过修改is_user_logged_in()的返回值就对“编辑”按钮不生效了。再来看评论头像。修改了is_user_logged_in()的返回值之后,头像旁边的文字已经变成了未登录状态下的文字,但是头像依然是先森的管理员评论头像。再去查看代码,发现评论头像部分虽然也使用了is_user_logged_in()函数,但是还另外使用了一个全局变量,代码大致如下:global $current_user;get_currentuserinfo();...echo get_avatar( $current_user->user_email, $size = '48' ,'');这样是通过获取当前用户信息,然后来获取用户的email邮箱地址,这样就和is_user_logged_in()函数无关了,因此前台还是会显示管理员的头像。但也正是这个问题,让先森找到了解决的办法。让管理员在前台匿名评论头像是通过获取当前登录用户的相关信息,进而获取用户邮箱来显示头像的。用到的获取用户信息函数是:get_currentuserinfo()而其实看is_user_logged_in()函数,其实它也有获取当前用户的相关信息,但用的是另一个函数:$user = wp_get_current_user();而这两个函数,其实是同一个函数,只是wp_get_current_user()是get_currentuserinfo()的进阶版:Notice: 自4.5.0版本起,已不建议使用get_currentuserinfo,请换用wp_get_current_user()。 in ***\wp-includes\functions.php on line 3707既然如此,只需要让当前用户信息为空即可。在自己的主题function.php最后加入以下代码,那么在前台就用户信息就为空了,即获取不到用户信息了:/*** 让管理员在前台访问匿名** //www.capjsj.cn/make_known_users_anonymous.html*/function make_known_users_anonymous() { global $current_user; if(!is_admin()){ $current_user = array( 'user_login' => '', 'user_email' =>'', 'user_level' => '', 'user_firstname' => '', 'user_lastname' => '', 'display_name' => '', 'ID' => '', 'user_url' => '', ); } return $current_user;}add_action( 'init', 'make_known_users_anonymous' );如果想要调试的话,可以把以下代码放在前台页面中想放的位置:<?php global $current_user; get_currentuserinfo(); //或者将这两行换成 $current_user = wp_get_current_user();if( is_user_logged_in()){ echo '已经登录';}else{ echo '没有登录';}echo('Username: ' . $current_user->user_login . "\n"); //输出用户名 ?>但目前这种方式有个BUG,那就是在文章编辑页面点击预览的时候会返回404,这个待先森找找解决方法。2017-09-01更新先森看了下,预览的页面会在文章链接后面加上“?preview=true”或者“?p=xxx&preview=true”,那么,当访问链接是带了“preview=true”的,就不清除登录信息就行了。那么,把上面的匿名代码改成下面的代码,加入functions.php中/*** 让管理员在前台访问匿名** //www.capjsj.cn/make_known_users_anonymous.html*/function make_known_users_anonymous() { global $current_user; if(!is_admin() && $_GET['preview'] != 'true'){ $current_user = array( 'user_login' => '', 'user_email' =>'', 'user_level' => '', 'user_firstname' => '', 'user_lastname' => '', 'display_name' => '', 'ID' => '', 'user_url' => '', ); } return $current_user;}add_action( 'init', 'make_known_users_anonymous' );如果有任何问题,可以在下方评论。关于访客填写的昵称、邮箱、域名等信息不被CDN缓存,可以看看先森的解决方案:用cookie解决网站开启CDN缓存之后已知用户头像昵称被缓存等系列问题用cookie记住用户信息后隐藏信息输入框,优化用户体验