<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Backend | Easton Man's Blog</title>
	<atom:link href="https://blog.eastonman.com/blog/tag/backend/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.eastonman.com</link>
	<description>临渊羡鱼，不如退而结网</description>
	<lastBuildDate>Wed, 26 Aug 2020 01:05:59 +0000</lastBuildDate>
	<language>zh-Hans</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1.2</generator>

<image>
	<url>https://blog.eastonman.com/wp-content/uploads/2021/02/cropped-Logo-e1613298891313-32x32.png</url>
	<title>Backend | Easton Man's Blog</title>
	<link>https://blog.eastonman.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>服务器性能监控实践（一）—— 技术选型</title>
		<link>https://blog.eastonman.com/blog/2019/02/fu-wu-qi-xing-neng-jian-kong-shi-jian-1/</link>
					<comments>https://blog.eastonman.com/blog/2019/02/fu-wu-qi-xing-neng-jian-kong-shi-jian-1/#respond</comments>
		
		<dc:creator><![CDATA[Easton Man]]></dc:creator>
		<pubDate>Mon, 11 Feb 2019 21:46:00 +0000</pubDate>
				<category><![CDATA[未分类]]></category>
		<category><![CDATA[Backend]]></category>
		<category><![CDATA[Original]]></category>
		<guid isPermaLink="false">https://blog.eastonman.com/2019/02/11/fu-wu-qi-xing-neng-jian-kong-shi-jian-1/</guid>

					<description><![CDATA[<p>本文主要介绍现阶段可快速构建的服务器性能监控系统，通过对比选出适用于作者所用场景的轻量级、可扩展性强的监控系统</p>
The post <a href="https://blog.eastonman.com/blog/2019/02/fu-wu-qi-xing-neng-jian-kong-shi-jian-1/">服务器性能监控实践（一）—— 技术选型</a> first appeared on <a href="https://blog.eastonman.com">Easton Man's Blog</a>.]]></description>
										<content:encoded><![CDATA[<p class="wpwc-reading-time">预计阅读时间： 8 分钟</p>
<p class="wp-block-paragraph"></p>



<div class="wp-block-group"><div class="wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow">
<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="960" height="273" src="https://blog.eastonman.com/wp-content/uploads/2020/07/3713134454-1.png" alt="" class="wp-image-77" srcset="https://blog.eastonman.com/wp-content/uploads/2020/07/3713134454-1.png 960w, https://blog.eastonman.com/wp-content/uploads/2020/07/3713134454-1-300x85.png 300w, https://blog.eastonman.com/wp-content/uploads/2020/07/3713134454-1-768x218.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></figure>
</div></div>



<p class="wp-block-paragraph">本文基于的应用场景是作者个人维护十数台可用性要求不是很高的非生产环i8境服务器（个人博客，团队git服务器等）。</p>



<p class="wp-block-paragraph">那么这样的应用场景要求选用的系统尽量满足一下特性：</p>



<ul class="wp-block-list"><li>免费/开源/便宜</li><li>快速</li><li>轻量</li><li>可扩展性强</li></ul>



<p class="wp-block-paragraph">目前作者接触到的服务器监控系统大概有那么几个，全部都基于开源软件。传统老牌监控系统Zabbix和Nagios、基于Prometheus的监控系统解决方案和基于InfluxDB的解决方案。对比了这些方案后，作者选出了一种最适合的系统，只想看结论的同学请直接翻到文末。</p>



<h1 class="wp-block-heading" id="zabbix-nagios">Zabbix 和 Nagios</h1>



<h2 class="wp-block-heading" id="zabbix">Zabbix</h2>



<div class="wp-block-image kg-card kg-image-card"><figure class="aligncenter size-large is-resized"><img decoding="async" src="https://blog.eastonman.com/wp-content/uploads/2020/08/3751213830.png" alt="" class="wp-image-112" width="370" height="255" srcset="https://blog.eastonman.com/wp-content/uploads/2020/08/3751213830.png 968w, https://blog.eastonman.com/wp-content/uploads/2020/08/3751213830-300x206.png 300w, https://blog.eastonman.com/wp-content/uploads/2020/08/3751213830-768x528.png 768w" sizes="(max-width: 370px) 100vw, 370px" /></figure></div>



<div class="wp-block-image kg-card kg-image-card"><figure class="aligncenter size-large is-resized"><img decoding="async" src="https://blog.eastonman.com/wp-content/uploads/2020/08/1522319286.png" alt="" class="wp-image-113" width="341" height="303" srcset="https://blog.eastonman.com/wp-content/uploads/2020/08/1522319286.png 970w, https://blog.eastonman.com/wp-content/uploads/2020/08/1522319286-300x267.png 300w, https://blog.eastonman.com/wp-content/uploads/2020/08/1522319286-768x684.png 768w" sizes="(max-width: 341px) 100vw, 341px" /></figure></div>



<p class="wp-block-paragraph">Zabbix 作为老牌的企业级服务器监控系统，功能非常强大。<br>官方介绍有许多功能，包括：</p>



<ul class="wp-block-list"><li>几乎所有协议和数据结构的数据来源（包括SNMP, IPMI等基础设施管理协议）</li><li>极其丰富的配置项</li><li>丰富的API控制</li><li>完全的用户权限和认证系统，提供PAM支持</li><li>一站式的解决方案，可提供图表绘制、日志审查、报警等所有可能用到的健康度监控工具</li><li>自动发现设备和数据来源</li><li>自动化维护和检查</li><li>可自定义的前端样式</li></ul>



<p class="wp-block-paragraph">功能强大的同时也相应的会带来重量级的问题，官方文档给出的要求是100个监控项的数量级至少需要128MB内存和256M硬盘来安装，实际使用中一般需要1GB内存和100G左右的硬盘来保证比较良好的可用性。<br>不过这样的问题仅仅是对于小规模应用场景来说的，真正企业级的应用中zabbix还是属于相当轻量的，也是当之无愧的首选。<br>Zabbix虽然提供了高度的可定制性和多到令人厌烦的配置选项，但是作为一站式方案的系统，系统耦合度很高，不利于大型、实力强的企业做二次开发和组件替换。<br>我个人在一年多前使用过一会zabbix，安装并不困难，甚至比Mysql的安装配置都简单，但是完成后监控配置十分负复杂，对于两位数的机器没有必要如此细致的配置。Zabbix适用于中型企业专门雇有2-3人运维团队的场景，对于个人非专职而言全套系统一一配置下来还是显得过于繁杂。<br>当然，Zabbix仍然不失为一个优秀的监控系统。</p>



<h1 class="wp-block-heading" id="nagios">Nagios</h1>



<figure class="wp-block-image size-large is-resized kg-card kg-image-card"><img loading="lazy" decoding="async" src="https://blog.eastonman.com/wp-content/uploads/2020/08/765332687.png" alt="" class="wp-image-114" width="266" height="185"/></figure>



<p class="wp-block-paragraph">Nagios相比于Zabbix似乎更为的重量级，至少需要1GB的内存和8GB的硬盘来完成一次完整的安装。<br>与Zabbix提供的一体式解决方案不同，Nagios的系统更加组件化，提供给大型企业更大的自定义空间，组件间耦合度较Zabbix低。<br>我自己未安装使用过Nagios，因此不作过多评价。</p>



<p class="wp-block-paragraph">总体而言，Zabbix和Nagios都是企业级的监控方案，主要面对企业用户开发，也适用于企业的应用场景。但是其部署和配置的过程十分烦琐，不符合我们“快速”的宗旨，所以不是特别合适。</p>



<h1 class="wp-block-heading" id="-">第三方监控服务</h1>



<p class="wp-block-paragraph">第三方提供的监控服务从简单到复杂，从免费到收费，几乎应有尽有，只要你肯出钱，没有找不到的解决方案。如果你比较不愿意自己动手搭建，或者不愿意雇佣专职运维，这样的外包服务在公司规模较小的情况下还是很常见的。<br>当然，这很难满足我们“免费/便宜”原则，可扩展性相比于前文的两个企业解决方案更差。所以第三方的监控服务更适用于希望能够直接外包运维的非互联网甚至非技术型企业。</p>



<h1 class="wp-block-heading" id="-prometheus">基于Prometheus</h1>



<p class="wp-block-paragraph">基于Prometheus的监控系统架构一般如下</p>



<figure class="wp-block-image size-large is-resized kg-card kg-image-card"><img loading="lazy" decoding="async" src="https://blog.eastonman.com/wp-content/uploads/2020/08/2917840214-1024x615.png" alt="" class="wp-image-141" width="524" height="314" srcset="https://blog.eastonman.com/wp-content/uploads/2020/08/2917840214-1024x615.png 1024w, https://blog.eastonman.com/wp-content/uploads/2020/08/2917840214-300x180.png 300w, https://blog.eastonman.com/wp-content/uploads/2020/08/2917840214-768x461.png 768w, https://blog.eastonman.com/wp-content/uploads/2020/08/2917840214.png 1351w" sizes="(max-width: 524px) 100vw, 524px" /></figure>



<p class="wp-block-paragraph">或是这个简化版</p>



<figure class="wp-block-image size-large kg-card kg-image-card"><img loading="lazy" decoding="async" width="960" height="273" src="https://blog.eastonman.com/wp-content/uploads/2020/08/3713134454-1-1.png" alt="" class="wp-image-142" srcset="https://blog.eastonman.com/wp-content/uploads/2020/08/3713134454-1-1.png 960w, https://blog.eastonman.com/wp-content/uploads/2020/08/3713134454-1-1-300x85.png 300w, https://blog.eastonman.com/wp-content/uploads/2020/08/3713134454-1-1-768x218.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></figure>



<p class="wp-block-paragraph">Prometheus本身是一个时序数据库套件，提供了监控系统中的数据收集服务端和数据库的角色（也就是上图中的Prometheus Server部分），官方还提供了报警管理的模块（上图中Alert Manager)，因此我们还额外需要数据展示和数据收集的客户端（上图中Prometheus Target和Data Visualization）。</p>



<p class="wp-block-paragraph">这一额外的部分有很多的选择。对于Target 可以有各种Exporter 在官方页面有列举。甚至任何支持metric格式输出的数据收集端，比如nNetdata、statsd等。数据可视化我们一般会选择Grafana，当然其它如Grafite等只要支持PromQL查询的都可以。</p>



<p class="wp-block-paragraph">此套解决方案我不久前部署过，它的优点很多，包括了全部开源，模块化，可扩展性强，可以docker部署，部署非常简单。它也较为的轻量，完全部署仅需30M左右的内存。当然硬盘占用是跟随着数据量的增大而增大的，无数据情况下大约占用200-300M的硬盘空间。</p>



<h1 class="wp-block-heading" id="-influxdb">基于InfluxDB</h1>



<h2 class="wp-block-heading" id="tick-">TICK栈</h2>



<figure class="wp-block-image size-large kg-card kg-image-card"><img loading="lazy" decoding="async" width="970" height="500" src="https://blog.eastonman.com/wp-content/uploads/2020/08/2353643527.jpg" alt="" class="wp-image-144" srcset="https://blog.eastonman.com/wp-content/uploads/2020/08/2353643527.jpg 970w, https://blog.eastonman.com/wp-content/uploads/2020/08/2353643527-300x155.jpg 300w, https://blog.eastonman.com/wp-content/uploads/2020/08/2353643527-768x396.jpg 768w" sizes="(max-width: 970px) 100vw, 970px" /></figure>



<p class="wp-block-paragraph">TICK是InfluxData官方主推的监控技术栈。<br>Telegraf+InfluxDB+Chronograf+Kapacitor，将整套系统拆分成为四个模块，模块化特征明显。因此任意支持InfluxDB读写的数据收集或者监控模块都可以使用。<br>TICK当然也可以使用docker-compose管理，无论是部署还是迁移都很方便。<br>Telegraf提供了近百种不同的系统健康信息收集，若是还不够用也可以自己写插件，具有非常强大的可扩展性。<br>Chronograf集成了Kapacitor的管理功能、InfluxDB的直接查询和Dashboard数据展示功能。不仅如此，前端设计也非常养眼。<br>同样地，TICK栈也拥有与Prometheus媲美的优势——轻量、可扩展性强等等。下面我们就会讲到使用Grafana扩展数据可视化的功能。</p>



<h2 class="wp-block-heading" id="ticgk-">TICGK栈</h2>



<p class="wp-block-paragraph">虽然官方开发的Chronograf已经拥有精美的图表可以显示，但是论数据可视化，Grafana是难以逾越的强大开源方案。因此我们在TICK中加入Grafana，成为TICGK栈，这样一来几乎所有的优点都被涵盖了。虽然五个容器会带来磁盘和内存占用增大的影响，但是对比于异常强大的功能和简单易用的界面，这个技术栈完全适合作者的应用场景。也许在高并发和大数据量的场景下TICGK栈表现会下降，但是作为个人使用，担心并发无疑是杞人忧天。</p>



<p class="wp-block-paragraph">毫无疑问，最后作者选择部署的就是TICGK栈，使用docker-compose管理（就几个容器没必要k8s吧）。目前状况良好，总体内存占用60M左右，设置了5s的时间粒度，15天周期后预计的硬盘使用是4GB，还是可以接受的。存在一个现象就是5s的粒度会带来Telegraf内存占用问题，开了很多Buffer，但是事实上Buffer什么的并不真正影响啊。</p>



<p class="wp-block-paragraph">看完作者的选型，你有什么想法呢？欢迎在评论区交流。<br>才疏学浅，若有错漏，也恳请指正。</p>



<p class="wp-block-paragraph">敬请期待下一篇——服务器性能监控（二）</p>The post <a href="https://blog.eastonman.com/blog/2019/02/fu-wu-qi-xing-neng-jian-kong-shi-jian-1/">服务器性能监控实践（一）—— 技术选型</a> first appeared on <a href="https://blog.eastonman.com">Easton Man's Blog</a>.]]></content:encoded>
					
					<wfw:commentRss>https://blog.eastonman.com/blog/2019/02/fu-wu-qi-xing-neng-jian-kong-shi-jian-1/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Tideways与Xhgui实现PHP性能分析实践</title>
		<link>https://blog.eastonman.com/blog/2018/11/use-tideways-and-xhgui-to-analyze-php-performance/</link>
					<comments>https://blog.eastonman.com/blog/2018/11/use-tideways-and-xhgui-to-analyze-php-performance/#respond</comments>
		
		<dc:creator><![CDATA[Easton Man]]></dc:creator>
		<pubDate>Sat, 10 Nov 2018 08:01:00 +0000</pubDate>
				<category><![CDATA[未分类]]></category>
		<category><![CDATA[Backend]]></category>
		<category><![CDATA[Original]]></category>
		<guid isPermaLink="false">https://blog.eastonman.com/2018/11/10/use-tideways-and-xhgui-to-analyze-php-performance/</guid>

					<description><![CDATA[<p>预计阅读时间： 7 分钟 对于生产环境下php响应缓慢的问题，一般我们可以把分析流程拆分为如下几步操作： 1. [&#8230;]</p>
The post <a href="https://blog.eastonman.com/blog/2018/11/use-tideways-and-xhgui-to-analyze-php-performance/">Tideways与Xhgui实现PHP性能分析实践</a> first appeared on <a href="https://blog.eastonman.com">Easton Man's Blog</a>.]]></description>
										<content:encoded><![CDATA[<p class="wpwc-reading-time">预计阅读时间： 7 分钟</p>
<p class="wp-block-paragraph">对于生产环境下php响应缓慢的问题，一般我们可以把分析流程拆分为如下几步操作：</p>



<p class="wp-block-paragraph">1.分析开发环境下执行是否会慢；</p>



<p class="wp-block-paragraph">如果是代码问题，在开发环境下就能检测出来；</p>



<p class="wp-block-paragraph">2.分析测试机器执行是否会慢；</p>



<p class="wp-block-paragraph">如果是数据库或者第三方扩展问题，在测试阶段就能检查出来。</p>



<p class="wp-block-paragraph">3.从生产环境下线一台机器，分析代码执行慢的原因；</p>



<p class="wp-block-paragraph">如果是机器的问题，在这一步才能检查出来。</p>



<p class="wp-block-paragraph">1，2，3步骤都需要去分析代码，看哪部分执行时间长。如果迫不得已在生产环境下调试代码，不但要耗费大量时间还可能导致用户流失。</p>



<p class="wp-block-paragraph">大多时候我们会使用第三方的分析工具xhprof来快速发现问题。‌‌xhprof是由facebook开发的一款非侵入式php性能分析框架。但是官方已经不在维护，也没有跟进php7，只能在php5上运行，tideways则是一直由商业公司在xhprof停止维护后fork出的版本，开源在<a href="https://github.com/tideways/php-xhprof-extension">Github</a>上（托管服务需付费，自行搭建免费），支持PHP7。‌‌显而易见，tideways是我们的选择。</p>



<p class="wp-block-paragraph">tideways扩展能把每条请求生成详细的执行日志，通过对日志做简单的分析就能看到程序哪部分耗时最长，这里可以使用xhprof的UI程序（xhprof生成的日志和tideways生成的日志格式通用），交互虽然不大友好但是够用了。‌‌当然，也可按照本文介绍使用xhgui来进行可视化的分析。</p>



<h2 class="wp-block-heading" id="-">先决条件</h2>



<p class="wp-block-paragraph">本文部署所用环境为Ubuntu 18.04 LTS，其它环境请自行研究类似的配置。</p>



<h2 class="wp-block-heading" id="-tideways">安装Tideways</h2>



<p class="wp-block-paragraph">由于部署环境php采用编译安装，故Tideways也采用编译安装。‌‌如果采用apt安装，也可以直接使用apt安装php-tideways。‌‌还可以使用pecl安装，具体方法不详细讲了。</p>



<pre class="wp-block-code"><code>‌git clone https://github.com/tideways/php-xhprof-extension
cd php-xhprof-extension phpize ./configure make make install //sudo make install if not root</code></pre>



<p class="wp-block-paragraph">配置php.ini，加入</p>



<pre class="wp-block-code"><code>extension=tideways_xhprof.so tideways.auto_prepend_library=0 //optional </code></pre>



<p class="wp-block-paragraph">注意最好加上后面那行，因为如果不加，tideways会调试所有经过php-fpm的请求，包括xhgui的请求，而这些请求不是我们想看的。</p>



<h2 class="wp-block-heading" id="-xhgui">安装xhgui</h2>



<p class="wp-block-paragraph">其实xhgui就是一个网站程序，建过站的同学都知道大概怎么回事，只不过数据库换用了mongodb而已。</p>



<h3 class="wp-block-heading" id="-mongodb">安装mongodb</h3>



<p class="wp-block-paragraph">因为xhgui需要储存由tideways传入的信息，所以需要安装mongodb。‌‌另有人维护了一个mysql版本的<a href="https://github.com/preinheimer/xhprof">xhgui</a>，如果不喜欢mongodb可以换用。‌‌部署环境使用了oneinstack安装lnmp栈，所以也使用oneinstack安装mongodb</p>



<pre class="wp-block-code"><code>wget http://mirrors.linuxeye.com/oneinstack.tar.gz tar zxf oneinstack.tar.gz
cd oneinstack ./install.sh // sudo install.sh if not root </code></pre>



<p class="wp-block-paragraph">按照提示交互式安装mongodb就行了。‌‌如果你不想这么麻烦或者非生产环境部署，也可以直接使用apt安装：apt install mongodb<code> </code></p>



<p class="wp-block-paragraph">如果没有在php中加入mongodb扩展，则需继续安装mongodb扩展。</p>



<pre class="wp-block-code"><code>git clone https://github.com/mongodb/mongo-php-driver.git
cd mongo-php-driver
git submodule update --init phpize ./configure make make install // add sudo if not root >‌</code></pre>



<p class="wp-block-paragraph">同样地，在php.ini中添加extension=mongodb.so<code> </code></p>



<p class="wp-block-paragraph">官方基于性能建议我们为mongodb添加索引</p>



<pre class="wp-block-code"><code>$ mongo "use xhprof";
db.results.ensureIndex( { 'meta.SERVER.REQUEST_TIME' : -1 } ) &amp;gt;
db.results.ensureIndex( { 'profile.main().wt' : -1 } ) &amp;gt;
db.results.ensureIndex( { 'profile.main().mu' : -1 } ) &amp;gt;
db.results.ensureIndex( { 'profile.main().cpu' : -1 } ) &amp;gt;
db.results.ensureIndex( { 'meta.url' : 1 } ) &amp;gt;
db.results.ensureIndex( { 'meta.simple_url' : 1 } )</code></pre>



<p class="wp-block-paragraph">至此mongodb算是安装完毕。‌‌注意生产环境安装还需要为mongodb配置访问权限，此处不详细讨论了。</p>



<h3 class="wp-block-heading" id="-xhgui-1">下载xhgui</h3>



<pre class="wp-block-code"><code>‌ git clone https://github.com/perftools/xhgui</code></pre>



<p class="wp-block-paragraph">代码下载完以后上传到网站目录，具体操作因环境而异，若不熟悉请先熟悉lnmp架构。‌‌上传完后执行</p>



<pre class="wp-block-code"><code>‌ php /wwwroot/install.php</code></pre>



<h2 class="wp-block-heading" id="-nginx">配置Nginx</h2>



<p class="wp-block-paragraph">假设我们需要调试的网站位于dev.fqdn‌‌而xhgui位于xhgui.fqdn</p>



<p class="wp-block-paragraph">则需要在dev.fqdn配置文件的location段加入</p>



<pre class="wp-block-code"><code>‌fastcgi_param PHP_VALUE "auto_prepend_file=/wwwroot of xhfui.fqdn/xhgui/external/header.php"; </code></pre>



<p class="wp-block-paragraph">此配置的作用是在dev.fqdn下的每个php经过fastcgi的时候自动在开头加入这个xhgui/external/header.php‌‌而这个文件的作用是运行你的代码前调用tideways开启调试‌‌你的代码运行完毕后结束调试并把结果传入mongodb等待查看。</p>



<p class="wp-block-paragraph">xhgui.fqdn配置则是正常php网站的配置，不赘述了。‌‌注意需有这一行</p>



<p class="wp-block-paragraph">‌                              <code>location / {     try_files $uri $uri/ /index.php?$args; } </code></p>



<h2 class="wp-block-heading" id="-tideways-1">配置tideways</h2>



<p class="wp-block-paragraph">tideways的配置文件位于/config/config.php‌‌安装时这个文件不存在，故需要把默认配置复制到这个文件</p>



<p class="wp-block-paragraph">‌                              <code>cp &lt;wwwroot>/config/config.default.php &lt;wwwroot>/config/config.php </code></p>



<p class="wp-block-paragraph">除了mongodb链接配置（一般无需调整）‌‌主要关注这一个回调函数</p>



<p class="wp-block-paragraph">‌ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<code>// In config/config.php return array( &nbsp; &nbsp; // Other config &nbsp; &nbsp; 'profiler.enable' =&gt; function() { &nbsp; &nbsp; &nbsp; &nbsp; return rand(1, 100) === 42; &nbsp; &nbsp; } ); </code></p>



<ul class="wp-block-list"><li>‌</li></ul>



<p class="wp-block-paragraph">默认配置的此函数仅仅做了节流，截取1%的流量进行分析。这是基于生产环境的性能考虑，如果我们仅仅是在开发环境中使用，就不需要管这么多了。‌‌例如</p>



<p class="wp-block-paragraph">‌ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<code>// In config/config.php return array( &nbsp; &nbsp; // Other config &nbsp; &nbsp; 'profiler.enable' =&gt; function() { &nbsp; &nbsp; &nbsp; &nbsp; return true; &nbsp; &nbsp; } ); </code></p>



<ul class="wp-block-list"><li>‌</li></ul>



<p class="wp-block-paragraph">这个配置就会把所有流量全部截取分析。‌‌令人哭笑不得的是，这所有流量包括了xhgui.fqdn的流量，这显然不是我们想要分析的。‌‌还有的时候我们也不想看到dev.fqdn中管理界面的流量，这就需要一些进阶配置了。‌‌例如</p>



<p class="wp-block-paragraph">‌ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<code>'profiler.enable' =&gt; function() { &nbsp; &nbsp; &nbsp; &nbsp; $url = $_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI']; &nbsp; &nbsp; &nbsp; &nbsp; if (strpos($url, 'dev.fqdn/admin') === 0) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return false; &nbsp; &nbsp; &nbsp; &nbsp; } elseif (strpos($url, 'dev.kucloud.win') === 0) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return true; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; return false; &nbsp; &nbsp; }, </code></p>



<ul class="wp-block-list"><li>‌</li></ul>



<p class="wp-block-paragraph">这样一来就只会看到我们希望分析的请求了。</p>



<p class="wp-block-paragraph">参考：‌‌</p>



<p class="wp-block-paragraph"><a href="https://phperzh.com/articles/3235">phperzh</a>‌‌</p>



<p class="wp-block-paragraph"><a href="https://github.com/perftools/xhgui/blob/master/README.md">Xhgui </a></p>



<p class="wp-block-paragraph"><a href="https://github.com/perftools/xhgui/blob/master/README.md">Readme</a></p>The post <a href="https://blog.eastonman.com/blog/2018/11/use-tideways-and-xhgui-to-analyze-php-performance/">Tideways与Xhgui实现PHP性能分析实践</a> first appeared on <a href="https://blog.eastonman.com">Easton Man's Blog</a>.]]></content:encoded>
					
					<wfw:commentRss>https://blog.eastonman.com/blog/2018/11/use-tideways-and-xhgui-to-analyze-php-performance/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Typecho性能优化实践</title>
		<link>https://blog.eastonman.com/blog/2018/07/typecho-performance-optimisation/</link>
					<comments>https://blog.eastonman.com/blog/2018/07/typecho-performance-optimisation/#respond</comments>
		
		<dc:creator><![CDATA[Easton Man]]></dc:creator>
		<pubDate>Thu, 05 Jul 2018 08:02:00 +0000</pubDate>
				<category><![CDATA[未分类]]></category>
		<category><![CDATA[Backend]]></category>
		<category><![CDATA[Original]]></category>
		<guid isPermaLink="false">https://blog.eastonman.com/2018/07/05/typecho-performance-optimisation/</guid>

					<description><![CDATA[<p>预计阅读时间： 5 分钟 本文将从全栈角度分析typecho性能提升关键，并最终实现首屏时间缩短到1s以内 文 [&#8230;]</p>
The post <a href="https://blog.eastonman.com/blog/2018/07/typecho-performance-optimisation/">Typecho性能优化实践</a> first appeared on <a href="https://blog.eastonman.com">Easton Man's Blog</a>.]]></description>
										<content:encoded><![CDATA[<p class="wpwc-reading-time">预计阅读时间： 5 分钟</p>
<div class="wp-block-group"><div class="wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow">
<p class="wp-block-paragraph">本文将从全栈角度分析typecho性能提升关键，并最终实现首屏时间缩短到1s以内</p>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">文中服务器是用的是tsukaeru 日本2核1G内存 50G SSD 100Mbps网络的KVM架构vps 到国内电信延迟约150ms<br>IO约170MB/s(超过1Gbps), UnixBench 双核跑分1400左右<br>对于个人网站来说算是中等偏上的配置</p>



<h1 class="wp-block-heading" id="-">后端</h1>



<h2 class="wp-block-heading" id="php">PHP</h2>



<p class="wp-block-paragraph">php版本毋庸置疑地影响着以php架构的typecho的运行<br>php7 相比于php5.x 性能的提升是质的飞跃<br>同样的typecho版本分别在两个版本的php下执行时间想去甚远<br>在typecho根目录下执行index.php时间对比</p>



<pre class="wp-block-code"><code>user@fqdn:# time php index.php > /dev/null 2>&amp;1 
real    0m1.525s
user    0m0.180s
sys     0m0.036s
# php5.6.33
</code></pre>



<pre class="wp-block-code"><code>user@fqdn:# time php index.php > /dev/null 2>&amp;1 
real    0m0.178s
user    0m0.067s
sys     0m0.006s
# php7.2.7
</code></pre>



<p class="wp-block-paragraph">php性能直接影响TTFB(首字节时间)，趁早升级吧。</p>



<h2 class="wp-block-heading" id="opcache">Opcache</h2>



<p class="wp-block-paragraph"><code>Opcache</code>是php缓存器，类似的还有<code>eAccelerater</code>等。<br><code>Opcache</code>加入编译可以进一步加速高并发时php的效率<br>通常而言php官方源中已经加入Opcache，各大一键lnmp脚本或管理面板都会安装Opcache<br>以下是多次执行后再次执行index.php的耗时</p>



<pre class="wp-block-code"><code>user@fqdn:# time php index.php > /dev/null 2>&amp;1 
real    0m0.093s
user    0m0.037s
sys     0m0.007s
# php7.2.7 第二次执行
</code></pre>



<p class="wp-block-paragraph">可以看出，此时php执行已经非常快了，若是在国内或是香港的vps上，TTFB已经可以缩短到通常建议的300ms以下了</p>



<h2 class="wp-block-heading" id="mencached">Mencached</h2>



<p class="wp-block-paragraph">通常大型php站点都会配置页面缓存，这样在高并发下的性能优势非常突出。<br>typecho作为轻量级博客框架，并没有自带Memcached缓存的功能。好在插件总是万能的<br>推荐一个<a href="https://github.com/phpgao/TpCache">TpCache插件</a><br>支持Memcache, Memcached和Redis，功能算是比较完善的了。<br>开启缓存插件后高并发瓶颈从cpu性能变成了网络带宽(100Mbps占满)。</p>



<p class="wp-block-paragraph">下图是在loader.io压测下1700并发一分钟的结果</p>



<figure class="wp-block-image size-large is-resized kg-card kg-image-card"><img loading="lazy" decoding="async" src="https://blog.eastonman.com/wp-content/uploads/2020/08/2526434504-1024x875.jpg" alt="" class="wp-image-195" width="278" height="237" srcset="https://blog.eastonman.com/wp-content/uploads/2020/08/2526434504-1024x875.jpg 1024w, https://blog.eastonman.com/wp-content/uploads/2020/08/2526434504-300x256.jpg 300w, https://blog.eastonman.com/wp-content/uploads/2020/08/2526434504-768x656.jpg 768w, https://blog.eastonman.com/wp-content/uploads/2020/08/2526434504.jpg 1076w" sizes="(max-width: 278px) 100vw, 278px" /></figure>



<figure class="wp-block-image size-large is-resized kg-card kg-image-card"><img loading="lazy" decoding="async" src="https://blog.eastonman.com/wp-content/uploads/2020/08/3243333678-1024x736.jpg" alt="" class="wp-image-197" width="286" height="206" srcset="https://blog.eastonman.com/wp-content/uploads/2020/08/3243333678-1024x736.jpg 1024w, https://blog.eastonman.com/wp-content/uploads/2020/08/3243333678-300x216.jpg 300w, https://blog.eastonman.com/wp-content/uploads/2020/08/3243333678-768x552.jpg 768w, https://blog.eastonman.com/wp-content/uploads/2020/08/3243333678.jpg 1080w" sizes="(max-width: 286px) 100vw, 286px" /></figure>



<figure class="wp-block-image size-large is-resized kg-card kg-image-card"><img loading="lazy" decoding="async" src="https://blog.eastonman.com/wp-content/uploads/2020/08/2497857299-1024x987.jpg" alt="" class="wp-image-196" width="265" height="255" srcset="https://blog.eastonman.com/wp-content/uploads/2020/08/2497857299-1024x987.jpg 1024w, https://blog.eastonman.com/wp-content/uploads/2020/08/2497857299-300x289.jpg 300w, https://blog.eastonman.com/wp-content/uploads/2020/08/2497857299-768x740.jpg 768w, https://blog.eastonman.com/wp-content/uploads/2020/08/2497857299.jpg 1079w" sizes="(max-width: 265px) 100vw, 265px" /></figure>



<p class="wp-block-paragraph">安利一下loader.io，这是一个sendgrid旗下的压力测试工具，免费版最高可以使用美每秒850新链接。</p>



<p class="wp-block-paragraph">此时服务器cpu占用仍维持在80%左右，nginx两个worker process 各30% ，memcached 和php-fpm 均在10%以下<br>mysql为0%</p>



<p class="wp-block-paragraph">实际可以达到的并发数大概在1000~1100并发左右，这对于个人网站来说，除非遭到ddcc，根本不可能有如此大的并发数。</p>



<h2 class="wp-block-heading" id="nginx">Nginx</h2>



<h3 class="wp-block-heading" id="worker-process">Worker Process</h3>



<p class="wp-block-paragraph">一般而言推荐保持和CPU核心数一样，比如2。<br>默认的配置是1，如果在多核服务器上这会导致CPU仅利用一核。<br>也可以配置为auto。</p>



<h3 class="wp-block-heading" id="tcpfastopen">TcpFastOpen</h3>



<p class="wp-block-paragraph">TFO 可以使在session过期前再次发起tcp链接的时候不需要再次进行3次握手，直接传输数据，对于服务器放在国外的网站还是很有用的，tcp握手通常需要花费200ms以上的时间，这对于1s左右的加载时间还是不可忽视的。</p>



<p class="wp-block-paragraph">在Nginx配置的server段监听端口后添加tcpfastopen=3</p>



<p class="wp-block-paragraph">如</p>



<pre class="wp-block-code"><code>listen 443 ssl tcpfastopen=3 ;
</code></pre>



<h2 class="wp-block-heading" id="linux-kernel">Linux Kernel</h2>



<p class="wp-block-paragraph">同样也有tcpfastopen 设置，开启方法大家google一下</p>



<p class="wp-block-paragraph">推荐开启BBR tcp拥塞算法<br>对于Ubuntu 16.04, 可以执行</p>



<pre class="wp-block-code"><code>echo 'net.core.default_qdisc=fq' >> /etc/sysctl.conf
echo 'net.ipv4.tcp_congestion_control=bbr' >> /etc/sysctl.conf
</code></pre>



<p class="wp-block-paragraph">如果系统默认的文件打开数太小，可以扩大一些<br>比如Ubuntu默认1024，高并发时可能会出现文件打开数过多的错误。<br>使用以下命令</p>



<pre class="wp-block-code"><code>ulimit -n 50000
</code></pre>



<p class="wp-block-paragraph">可以添加到启动脚本以实现每次开机自动调整nofile限制。</p>



<h1 class="wp-block-heading" id="--1">前端</h1>



<h2 class="wp-block-heading" id="js-">js异步加载</h2>



<p class="wp-block-paragraph">非异步加载的JavaScript会阻塞DOM load事件，因为js可以修改dom tree 故浏览器在js执行时不会进行渲染。<br>但是其实很多js都是不操作dom树的，比如用户统计所用的js和页面交互的js。我们可以使用 async 和defer 使得这些js的加载不阻塞浏览器渲染</p>



<h2 class="wp-block-heading" id="css-">CSS 压缩</h2>



<p class="wp-block-paragraph">css压缩是用gulp-minify 实现的，在主题发布时已经完成。</p>



<h2 class="wp-block-heading" id="pjax">PJAX</h2>



<p class="wp-block-paragraph">PJAX = pushState + AJAX<br>事实上就是ajax异步传输页面内容后用pushState更新浏览器历史记录，统计数据等。<br>这样使得我们不需要重新渲染页脚，侧栏等页面共有的部分。<br>实现方法可以参考New Material主题。<br>盲目地全页面pjax反倒是适得其反的。</p>



<h2 class="wp-block-heading" id="lazyload">Lazyload</h2>



<p class="wp-block-paragraph">非首屏图片懒加载，也就是直到图片进入视野中时才加载图面，这样在加载首屏时就可以节省很多时间。<br>实现方法也可以参考New Material主题。</p>



<h1 class="wp-block-heading" id="--2">最终效果</h1>



<figure class="wp-block-image size-large is-resized kg-card kg-image-card"><img loading="lazy" decoding="async" src="https://blog.eastonman.com/wp-content/uploads/2020/08/811845698-993x1024.jpg" alt="" class="wp-image-198" width="381" height="392" srcset="https://blog.eastonman.com/wp-content/uploads/2020/08/811845698-993x1024.jpg 993w, https://blog.eastonman.com/wp-content/uploads/2020/08/811845698-291x300.jpg 291w, https://blog.eastonman.com/wp-content/uploads/2020/08/811845698-768x792.jpg 768w, https://blog.eastonman.com/wp-content/uploads/2020/08/811845698.jpg 1047w" sizes="(max-width: 381px) 100vw, 381px" /></figure>



<figure class="wp-block-image size-large is-resized kg-card kg-image-card"><img loading="lazy" decoding="async" src="https://blog.eastonman.com/wp-content/uploads/2020/08/2004830255.jpg" alt="" class="wp-image-199" width="312" height="322" srcset="https://blog.eastonman.com/wp-content/uploads/2020/08/2004830255.jpg 655w, https://blog.eastonman.com/wp-content/uploads/2020/08/2004830255-290x300.jpg 290w" sizes="(max-width: 312px) 100vw, 312px" /></figure>



<p class="wp-block-paragraph">可以看到，在这样的网络延迟下，DOM树加载完毕仅在html下载完成后一百多毫秒，ttfb也是接近网络延迟，服务器处理时间仅有二十几毫秒。这次的性能优化还是很有效果的。</p>



<p class="wp-block-paragraph">水平有限，如有错误之处欢迎指正。</p>
</div></div>



<p class="wp-block-paragraph"></p>The post <a href="https://blog.eastonman.com/blog/2018/07/typecho-performance-optimisation/">Typecho性能优化实践</a> first appeared on <a href="https://blog.eastonman.com">Easton Man's Blog</a>.]]></content:encoded>
					
					<wfw:commentRss>https://blog.eastonman.com/blog/2018/07/typecho-performance-optimisation/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>博客搬迁拾遗</title>
		<link>https://blog.eastonman.com/blog/2018/06/blog-migration-note-0/</link>
					<comments>https://blog.eastonman.com/blog/2018/06/blog-migration-note-0/#respond</comments>
		
		<dc:creator><![CDATA[Easton Man]]></dc:creator>
		<pubDate>Fri, 08 Jun 2018 08:13:00 +0000</pubDate>
				<category><![CDATA[未分类]]></category>
		<category><![CDATA[Backend]]></category>
		<category><![CDATA[Original]]></category>
		<guid isPermaLink="false">https://blog.eastonman.com/2018/06/08/blog-migration-note-0/</guid>

					<description><![CDATA[<p>预计阅读时间： 4 分钟 最近把博客从RFCHost家的洛杉矶GIA CN2小鸡上搬到tsukaeru的日本I [&#8230;]</p>
The post <a href="https://blog.eastonman.com/blog/2018/06/blog-migration-note-0/">博客搬迁拾遗</a> first appeared on <a href="https://blog.eastonman.com">Easton Man's Blog</a>.]]></description>
										<content:encoded><![CDATA[<p class="wpwc-reading-time">预计阅读时间： 4 分钟</p>
<p><!--kg-card-begin: markdown--></p>
<p>最近把博客从RFCHost家的洛杉矶GIA CN2小鸡上搬到tsukaeru的日本IIJ线路的VPS上，价格相差无几，但tsukaeru家的适合建站，所以我就把博客搬过来了</p>
<p>GIA CN2虽然线路很好，但是配置实在有点低(估计主要跨Wa11上网用)。tsu家这台IO非常不错，接近bwg家的1Gbps<br />
,还给免费50G备份空间，2H1G 50G SSD。原来那台是1H512M 10G SSD ,装完lnmp就60%占用了！最近tsu促销，果断搬迁博客。<br />
以下是搬迁过程中遇到的问题和解决方案</p>
<h2 id="accessdeniednoinputfilefound">Access denied &amp; No input file found</h2>
<p>这个是老问题了，网上也有很多地方有解释，官方安装教程也有。<br />
就是那个<code>cgi.fix_pathinfo</code><br />
把<code>php.ini</code>文件中的<code>cgi.fix_pathinfo=0</code>改成<code>cgi.fix_pathinfo=1</code>就行了<br />
<code>php.ini</code>文件在哪里？<br />
对于oneinstack安装的php，在<code>/usr/local/php/etc/php.ihi</code><br />
对于ubuntu系统自带的php在<code>/etc/php/fpm/php.ini</code><br />
实在找不到可以放大招：<code>phpinfo();</code><br />
在命令行使用交互模式(php -a)输入<code>phpinfo();</code>仔细找一找<code>php.ini</code>的位置<br />
什么？输出太多不想找？<br />
那只好系统帮我找一找了</p>
<pre><code>echo 'phpinfo();' &gt; 1.php
php 1.php | grep 'php.ini'
</code></pre>
<p>当然你也可以暴力一些</p>
<pre><code>find php.ini /
</code></pre>
<h2 id="404">首页正常二级页面全部404</h2>
<p>这是typecho伪静态的问题，需要向nginx配置文件http-&gt;server的内部添加</p>
<pre><code>if (!-e $request_filename) {
      rewrite ^(.*)$ /index.php$1 last;
}
</code></pre>
<h2 id="fastcgi_params">fastcgi_params配置</h2>
<p>nginx给出的默认配置文件在http-&gt;server-&gt;location块使用</p>
<pre><code>fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
include        fastcgi_params;
</code></pre>
<p>但是Oneinstack的处理是将SCRIPT_FILENAME加入fastcgi_params中，我个人认为这种做法更清晰明了，推荐这样的做法。</p>
<h2 id="">目录权限</h2>
<p>我每次安装typecho都是直接clone项目在复制的(反正最近的commit都是修bug)，有时会有权限问题<br />
根目录下</p>
<pre><code>var
usr/themes
usr/uploads
usr/plugins
</code></pre>
<p>这些目录最好都<br />
<code>chown -R www:www</code></p>
<h2 id="tpcache">缓存插件TpCache</h2>
<p><a href="https://github.com/phpgao/TpCache">Github项目</a><br />
这个插件应该是比较完善的，据作者readme,原生评论测试过可以更新缓存。第三方评论就更加没所谓啦。</p>
<p>启用之前要先在服务器安装好Memcached、memcache或Redis，据说Memcached在键值较大时性能较优，本博客就选择的是Memcached。<br />
当然一键包啦，安装和php扩展一并搞定。<br />
哦对了，推荐一键包Oneinstack<br />
直接下载<a href="http://mirrors.linuxeye.com/oneinstack.tar.gz">Oneinstack不含源码版</a><br />
个人认为比军哥的lnmp.org的要好(而且开源)</p>
<h2 id="comment2mail">Comment2Mail</h2>
<p>这是常规啦<br />
只是为什么总是发件人Root root@localhost<br />
我明明配置的是Sendgrid的smtp发信啊<br />
难道源码有问题？<br />
有谁知道吗？</p>
<h2 id="">数据迁移</h2>
<p>typecho自带的导出导入已经基本够用了<br />
但是之前曾经用过iviews插件，修改过数据库结构(也不告诉我&#8230;&#8230;)到了导入的时候出错了(typecho也真是奇怪，导出不检查数据库结构，导入检查)<br />
不想改动数据库，干脆在原来那里删了那张views表<br />
嗯<br />
所以还是我的NewMaterial主题好，用自定义字段统计，不乱改数据库。</p>
<p>暂时想到的就这些吧<br />
其他的服务器安全加固等等就不写在这里了</p>
<p><!--kg-card-end: markdown--></p>The post <a href="https://blog.eastonman.com/blog/2018/06/blog-migration-note-0/">博客搬迁拾遗</a> first appeared on <a href="https://blog.eastonman.com">Easton Man's Blog</a>.]]></content:encoded>
					
					<wfw:commentRss>https://blog.eastonman.com/blog/2018/06/blog-migration-note-0/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>PHP7.0+中isset()函数的行为变更</title>
		<link>https://blog.eastonman.com/blog/2018/06/isset-function-implement-change-in-php7/</link>
					<comments>https://blog.eastonman.com/blog/2018/06/isset-function-implement-change-in-php7/#respond</comments>
		
		<dc:creator><![CDATA[Easton Man]]></dc:creator>
		<pubDate>Mon, 04 Jun 2018 12:19:00 +0000</pubDate>
				<category><![CDATA[未分类]]></category>
		<category><![CDATA[Backend]]></category>
		<category><![CDATA[Original]]></category>
		<guid isPermaLink="false">https://blog.eastonman.com/2018/06/04/isset-function-implement-change-in-php7/</guid>

					<description><![CDATA[<p>预计阅读时间： 2 分钟 最近写模板又遇到问题了，同样的代码在测试机上正常工作，换到线上又出错了，后来一看，是 [&#8230;]</p>
The post <a href="https://blog.eastonman.com/blog/2018/06/isset-function-implement-change-in-php7/">PHP7.0+中isset()函数的行为变更</a> first appeared on <a href="https://blog.eastonman.com">Easton Man's Blog</a>.]]></description>
										<content:encoded><![CDATA[<p class="wpwc-reading-time">预计阅读时间： 2 分钟</p>
<p>最近写模板又遇到问题了，同样的代码在测试机上正常工作，换到线上又出错了，后来一看，是php7的锅&#8230;&#8230;</p>
<figure class="kg-card kg-image-card"><img decoding="async" src="https://blog.geekman.dev/wp-content/uploads/2020/08/5b42ef5037aa3.jpg" class="kg-image"></figure>
<p>php7+中isset()函数在判断类成员是否设置时的行为与php5.6有所不同。 我们先来看看php的官方git commit message</p>
<pre><code>
PHP 7 has fixed a bug with __isset which affects both the native isset and empty methods. This causes specific issues 
with checking isset or empty on relations in Eloquent. In PHP 7 checking if a property exists on an unloaded relation, 
for example isset($this-&gt;relation-&gt;id) is always returning false because unlike PHP 5.6, PHP 7 is now checking the offset of each attribute before chaining to the next one. In PHP 5.6 it would eager load the relation 
without checking the offset. This change brings back the intended behavior of the core Eloquent model __isset method 
for PHP 7 so it works like it did in PHP 5.6.

For reference, please check the following link, specifically Nikita Popov's comment (core PHP dev) - https://bugs.php.net/bug.php?id=69659

</code></pre>
<p>假设我们有如下php代码</p>
<pre><code>&lt;?php

class Post
{
    protected $attributes = ['foo' =&gt; 'bar'];

    public function __get($key)
    {
        if (isset($this-&gt;attributes[$key])) {
            return $this-&gt;attributes[$key];
        }
    }
}

$post = new Post();
echo isset($post-&gt;foo);  // false

</code></pre>
<p>我们会发现无论如何isset总是返回false<br />因为变量foo不是类Post的成员<br />也就是说，PHP7开始，isset执行前不会先执行-&gt;<br />也就是__get()函数</p>
<p>当然也可使用魔术方法__isset解决此问题</p>
<pre><code>
&lt;?PHP
class Post
{
    protected $attributes = ['foo' =&gt; 'bar'];

    public function __get($key)
    {
        if (isset($this-&gt;attributes[$key])) {
            return $this-&gt;attributes[$key];
        }
    }

    public function __isset($key)
    {
        if (isset($this-&gt;attributes[$key])) {
            return true;
        }

        return false;
    }
}

$post = new Post();
echo isset($post-&gt;foo);   //true

</code></pre>
<p>此时我们可以看到isset()返回了true<br />因为我们对类Post执行isset()时调用了我们定义的__isset()函数，而__isset()函数中的isset()是可以访问foo的，故此处返回true</p>
<p>当遇到<code>isset($widget-&gt;fields-&gt;$var)</code><br />这样的写法时<br />php5.6 和以前会先执行<code>$widget-&gt;fields-&gt;$var</code><br />php7则会在每次调用前执行isset<br />于是typecho常用的判断自定义字段是否为空的代码<br /><code>isset($widget-&gt;fields-&gt;$var)</code><br />总是返回false<br />网上大多数判断typecho自定义字段是否设置的教程都直接使用isset函数，当然会在php7的线上环境下出问题啊。<br />从兼容性角度考虑，建议还是写</p>
<pre><code>if ($widget-&gt;fields-&gt;$var !== NULL){
    //code...
}
</code></pre>
<p>比较保险。</p>The post <a href="https://blog.eastonman.com/blog/2018/06/isset-function-implement-change-in-php7/">PHP7.0+中isset()函数的行为变更</a> first appeared on <a href="https://blog.eastonman.com">Easton Man's Blog</a>.]]></content:encoded>
					
					<wfw:commentRss>https://blog.eastonman.com/blog/2018/06/isset-function-implement-change-in-php7/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>SSH公钥配置&#8211;从github导入</title>
		<link>https://blog.eastonman.com/blog/2018/04/ssh-public-key-import-from-github/</link>
					<comments>https://blog.eastonman.com/blog/2018/04/ssh-public-key-import-from-github/#respond</comments>
		
		<dc:creator><![CDATA[Easton Man]]></dc:creator>
		<pubDate>Fri, 06 Apr 2018 12:43:00 +0000</pubDate>
				<category><![CDATA[未分类]]></category>
		<category><![CDATA[Backend]]></category>
		<category><![CDATA[Original]]></category>
		<guid isPermaLink="false">https://blog.eastonman.com/2018/04/06/ssh-public-key-import-from-github/</guid>

					<description><![CDATA[<p>预计阅读时间： 1 分钟 原理 主要利用的是Github的公钥公开地址‌‌比如我的是Github keys‌‌ [&#8230;]</p>
The post <a href="https://blog.eastonman.com/blog/2018/04/ssh-public-key-import-from-github/">SSH公钥配置–从github导入</a> first appeared on <a href="https://blog.eastonman.com">Easton Man's Blog</a>.]]></description>
										<content:encoded><![CDATA[<p class="wpwc-reading-time">预计阅读时间： 1 分钟</p>
<p><!--kg-card-begin: markdown--></p>
<h1 id="">原理</h1>
<p><!--kg-card-end: markdown--></p>
<p>主要利用的是Github的公钥公开地址‌‌比如我的是<a href="https://github.com/manyang901.keys">Github keys</a>‌‌形如<code>https://githib.com/{username}.keys</code></p>
<h1 id="-">使用</h1>
<p>每次只要执行curl https://&#8230;. &gt;&gt; .ssh/authorized_keys‌‌就可以快速搞定了</p>
<p>还要注意权限问题，如果原本就有.ssh/authorzied_keys就没什么问题‌‌若是新创建的要.ssh 700‌‌.ssh/authorized_keys 600‌‌ssh对公钥读写还是有安全要求的。</p>
<p>居然有大佬写了个脚本？<a href="https://github.com/KiritoMiao/SSHKEY_Installer">SSHKEY_Installer</a></p>
<p>一阵无语&#8230;&#8230;</p>
<p>这个脚本有一个好，顺便帮忙关了密码登录。搞定了.ssh目录下的权限问题。</p>The post <a href="https://blog.eastonman.com/blog/2018/04/ssh-public-key-import-from-github/">SSH公钥配置–从github导入</a> first appeared on <a href="https://blog.eastonman.com">Easton Man's Blog</a>.]]></content:encoded>
					
					<wfw:commentRss>https://blog.eastonman.com/blog/2018/04/ssh-public-key-import-from-github/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>[转载]Systemd与Supervisord对比</title>
		<link>https://blog.eastonman.com/blog/2018/04/systemd-vs-supervisord/</link>
					<comments>https://blog.eastonman.com/blog/2018/04/systemd-vs-supervisord/#respond</comments>
		
		<dc:creator><![CDATA[Easton Man]]></dc:creator>
		<pubDate>Thu, 05 Apr 2018 08:52:00 +0000</pubDate>
				<category><![CDATA[未分类]]></category>
		<category><![CDATA[Backend]]></category>
		<guid isPermaLink="false">https://blog.eastonman.com/2018/04/05/systemd-vs-supervisord/</guid>

					<description><![CDATA[<p>预计阅读时间： 4 分钟 无论是Systemd和Supervisord都可以用于控制进程，实现进程的分组管理和 [&#8230;]</p>
The post <a href="https://blog.eastonman.com/blog/2018/04/systemd-vs-supervisord/">[转载]Systemd与Supervisord对比</a> first appeared on <a href="https://blog.eastonman.com">Easton Man's Blog</a>.]]></description>
										<content:encoded><![CDATA[<p class="wpwc-reading-time">预计阅读时间： 4 分钟</p>
</p>
<p><!--kg-card-begin: markdown--></p>
<p>无论是Systemd和Supervisord都可以用于控制进程，实现进程的分组管理和崩溃自动重启，下面我们看看他们都是怎么实现的。</p>
<h2 id="">进程控制</h2>
<p>无论 Supervisord 还是 Systemd，都采用 ini 作为配置文件的格式。跟 Supervisord 不同的是，Systemd 每个程序都要单独开一个 unit 文件。<br />
Supervisord 可以同时启动/停止配置文件中所以的进程（或者某个进程组配置中的进程）。<br />
也就是说，Supervisord 使用“进程组”这个概念来控制多个进程<br />
Systemd 则用用依赖来实现这一点。</p>
<p>我们来看一个简单的Systemd配置文件，实现了进程组管理</p>
<pre><code>; group.target
[Unit]
Description=Application
Wants=prog1.service prog2.service

</code></pre>
<pre><code>; prog1.service
[Unit]
Description=prog1
PartOf=group.target

[Service]
ExecStart=/usr/bin/prog1
Restart=on-failure
</code></pre>
<pre><code>; prog2.service
[Unit]
Description=prog2
PartOf=group.target

[Service]
ExecStart=/usr/bin/prog2
Restart=on-failure
</code></pre>
<p><code>systemctl start group.target</code> ，prog1 和 prog2 也会启动。<code>systemctl restart group.target</code>，prog1 和 prog2 也会跟着重启</p>
<p>相比起来Supervisord的管理方式就要明了一些了</p>
<pre><code>[program:prog1]
command=python /home/user/myapp/prog1.py

[program:prog2]
command=python /home/user/myapp/prog2.py

[group:prog]
programs=prog1,prog2
</code></pre>
<p><code>supervisorctl start prog:*</code>可以启动prog组下的所有进程</p>
<p>如果要更改 supervisord 的配置文件，supervisord 需要运行 supervisorctl reread 才会生效。<br />
而 systemd 则需要 systemctl daemon-reload。这方面两者差不多<br />
不过 supervisord 有一个优点。如果你不知道哪些程序的配置改变了，简单地执行 supervisorctl update，所有涉及的进程都会被重启。<br />
而 systemd 貌似做不到这一点。</p>
<p>systemd 可以指定 stop 操作时可以选择的命令（ExecStop=）。另外它还提供了 ExecReload=，可以自定义调用 systemctl reload xxx 重新读取程序配置文件时的操作。<br />
supervisord 不支持 reload 指定进程。同时对于 stop 操作，它只允许你选择要发送哪种信号&#8230;</p>
<p>supervisord 的 stopwaitsecs 可以控制 stop 操作后等待程序退出的耐心（以秒衡量）。待给定的耐心都消耗完毕后，supervisord 才会痛下杀手，发送 SIGKILL。<br />
systemd 对应的配置项是 TimeoutStopSec=。systemd 会给多一次机会，在下最后通牒之前，会先发送 SIGTERM，过另一个 TimeoutStopSec 之后才发送 SIGKILL。</p>
<h2 id="">对比</h2>
<p>systemd 和 supervisord 各有长短，不存在哪一方绝对的碾压。<br />
systemd 跟 Linux 紧密结合，主流的发行版几乎全部使用systemd，所需的依赖少，其提供的保障自然比 supervisord 更可靠。然而在强大的能力背后，也有配置复杂、不易上手等问题。<br />
systemd使用C语言编写，启动速度要快于supervisor，因此底层和对可用性有较高要求的情景，systemd还是更加适应的。<br />
supervisord 偏于应用层，却因此有独特的用武之地。<br />
举个例子，许多人会往 docker 打包里面封入一份 supervisord，让它来做 PID 1，以此稍微增强下健壮性。<br />
supervisord还有XMLRPC接口，使得它和上层应用更容易结合，无论是否是Python应用。</p>
<p>换 systemd 做同样的事，就像用园艺剪刀裁纸，即使能够顺利完成，也难免事倍功半。毕竟这样的方式跟 systemd 的设计是背道而驰的。</p>
<p>至于健壮性的对比，我没有做过实验不知道，但两者都是经过多年检验过的项目，健壮性对于小型服务来说都是足够好的了。</p>
<p><!--kg-card-end: markdown--></p>The post <a href="https://blog.eastonman.com/blog/2018/04/systemd-vs-supervisord/">[转载]Systemd与Supervisord对比</a> first appeared on <a href="https://blog.eastonman.com">Easton Man's Blog</a>.]]></content:encoded>
					
					<wfw:commentRss>https://blog.eastonman.com/blog/2018/04/systemd-vs-supervisord/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>[转载]dns.he.net 批量操作工具</title>
		<link>https://blog.eastonman.com/blog/2017/11/batch-script-for-dns-he-net/</link>
					<comments>https://blog.eastonman.com/blog/2017/11/batch-script-for-dns-he-net/#respond</comments>
		
		<dc:creator><![CDATA[Easton Man]]></dc:creator>
		<pubDate>Wed, 01 Nov 2017 14:16:00 +0000</pubDate>
				<category><![CDATA[未分类]]></category>
		<category><![CDATA[Backend]]></category>
		<guid isPermaLink="false">https://blog.eastonman.com/2017/11/01/batch-script-for-dns-he-net/</guid>

					<description><![CDATA[<p>预计阅读时间： 1 分钟 [萌咖][1]有个域名,托管在dns.he.net,有500多个A记录要删除.但是他 [&#8230;]</p>
The post <a href="https://blog.eastonman.com/blog/2017/11/batch-script-for-dns-he-net/">[转载]dns.he.net 批量操作工具</a> first appeared on <a href="https://blog.eastonman.com">Easton Man's Blog</a>.]]></description>
										<content:encoded><![CDATA[<p class="wpwc-reading-time">预计阅读时间： 1 分钟</p>
<p>[萌咖][1]有个域名,托管在dns.he.net,有500多个A记录要删除.<br />但是他官网不提供多选的功能.<br />所以花了点时间写了一个工具,支持批量删除记录.</p>
<p>特点:</p>
<p>支持删除操作.<br />支持适配sub,进行删除.<br />支持添加记录.<br />更多待续…<br />用法:</p>
<p>下载地址:</p>
<pre><code>wget --no-check-certificate -qO 'he.sh' 'https://moeclub.org/attachment/LinuxShell/he.sh' &amp;&amp; chmod a+x he.sh

</code></pre>
<h1 id="-">使用:</h1>
<ul>
<li>可用参数</li>
</ul>
<pre><code>bash he.sh -u [用户名] -p [密码] -del/-add -sub -d [域名] -n [子域] -r [记录] -t [记录类型]
</code></pre>
<ul>
<li>添加一个记录</li>
</ul>
<pre><code>bash he.sh -u [用户名] -p [密码] -add -d [域名] -n [子域] -r [记录] -t [记录类型]
</code></pre>
<ul>
<li>删除一个记录</li>
</ul>
<pre><code>bash he.sh -u [用户名] -p [密码] -del -d [域名] -n [子域]
</code></pre>
<ul>
<li>删除一批以某些字符开头的记录</li>
</ul>
<pre><code>bash he.sh -u [用户名] -p [密码] -del -sub -d [域名] -n [子域]
</code></pre>
<h1 id="--1">解释:</h1>
<p>www.moeclub.org<br />子域: www<br />域名: moeclub.org</p>
<p>全文转载自[萌咖][1]<br />[1]: <a href="https://moeclub.org">https://moeclub.org</a></p>The post <a href="https://blog.eastonman.com/blog/2017/11/batch-script-for-dns-he-net/">[转载]dns.he.net 批量操作工具</a> first appeared on <a href="https://blog.eastonman.com">Easton Man's Blog</a>.]]></content:encoded>
					
					<wfw:commentRss>https://blog.eastonman.com/blog/2017/11/batch-script-for-dns-he-net/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>在Daocloud上部署私有云</title>
		<link>https://blog.eastonman.com/blog/2017/10/deploy-private-cloud-service-on-daocloud/</link>
					<comments>https://blog.eastonman.com/blog/2017/10/deploy-private-cloud-service-on-daocloud/#respond</comments>
		
		<dc:creator><![CDATA[Easton Man]]></dc:creator>
		<pubDate>Sun, 29 Oct 2017 02:13:00 +0000</pubDate>
				<category><![CDATA[未分类]]></category>
		<category><![CDATA[Backend]]></category>
		<category><![CDATA[Original]]></category>
		<guid isPermaLink="false">https://blog.eastonman.com/2017/10/29/deploy-private-cloud-service-on-daocloud/</guid>

					<description><![CDATA[<p>预计阅读时间： 4 分钟 Daocloud目前免费提供两个docker容器供大家免费使用，有没有想过用它们来干 [&#8230;]</p>
The post <a href="https://blog.eastonman.com/blog/2017/10/deploy-private-cloud-service-on-daocloud/">在Daocloud上部署私有云</a> first appeared on <a href="https://blog.eastonman.com">Easton Man's Blog</a>.]]></description>
										<content:encoded><![CDATA[<p class="wpwc-reading-time">预计阅读时间： 4 分钟</p>
<p>Daocloud目前免费提供两个docker容器供大家免费使用，有没有想过用它们来干些什么？<br />Daocloud目前提供2个docker容器共免费使用，所以就可以自己做一个小小的私有云啦！要是你想要更多的空间或是更快的响应速度和带宽，可以购买更多容器集群，14元rmb一个容器每月。</p>
<hr>
<h2 id="-">为什么要选择私有云</h2>
<p>有人可能会问，既然百度、360、微云都已经做的可以了，速度不算太慢，存储空间甚至大的恐怖，那为什么还要使用私有云啊？<br />使用公有云有几个弊端：</p>
<ul>
<li>个人隐私难以保证。百度等云盘有“秒传”功能，实际上就是在上传前先检测在服务器上是否有相同的文件，然后把这个文件转到你的盘里。可是这样一来，你的数据毫无隐私可言了。国外的云盘一般都会保证不查看用户数据，但可惜都被墙了</li>
<li>数据安全难以保证。有没有发现你分享的文件可能过几个月甚至几天就失效啦？由于相关法律和规定删除了文件？国内的网盘都有这样的问题</li>
<li>对纯浏览器用户不友好。“高速下载请先安装百度云管家”“下载请用客户端登录”，怎么就不能直接下载呢？</li>
<li>捆绑的广告多。“试用加速包”“开通会员”，还有各种广告泛滥，怎么这么烦人啊</li>
</ul>
<p>这就是为什么我们需要私有云，私有云克服了几乎以上所有缺点：</p>
<ul>
<li>个人隐私保证。</li>
<li>数据掌握在自己手里。</li>
<li>无需客户端直接上传下载。</li>
<li>绝对干净无广告。</li>
<li>免费自带离线下载功能。</li>
<li>在线打开文件。</li>
<li>多用户管理。</li>
</ul>
<p>当然私有云也有缺点：</p>
<ul>
<li>免费空间少，多空间需付费。</li>
<li>响应相对慢。</li>
<li>需要一些技术知识</li>
</ul>
<p>当然相信看到这里的都是技术客，就不需要担心技术问题了</p>
<h2 id="--1">注册帐号</h2>
<p>注册这种事情就不说了，相信大家都懂</p>
<h2 id="-mysql">新建服务MySQL</h2>
<p>添加一个新的集成服务MySQL，Daocloud提供的两个容器其中一个就用在这里，可以获得128MB内存，2GB存储的MySQL服务，这时记住服务的内网IP地址、数据库名、用户名和密码。<br />如果喜欢postgreSQL可以换为postgreSQL，步骤基本相同</p>
<h2 id="-owncloud">新建镜像Owncloud</h2>
<p>在daocloud的镜像仓库里找到owncloud的镜像直接布署，或者如果你想要离线下载功能的话，可以找别人的owncloud-with-osdownload镜像布署，版本选最新的</p>
<h2 id="--2">绑定服务</h2>
<p>镜像布署完毕后选择绑定服务，绑定之前创建的MySQL</p>
<h2 id="-owncloud-1">配置owncloud</h2>
<p>通过Daocloud给的访问地址访问owncloud，会看到owncloud的配置界面，这时设置管理员帐号和密码，数据库选择MySQL/MariaDB（布署了postgreSQL的选择postgreSQL）输入刚才记下的服务IP、数据库名、用户名和密码，等待owncloud配置好数据库就可以啦，刷新页面就可以看到自己的owncloud私有云了</p>
<h2 id="--3"><s>这个私有云很安全稳定</s></h2>
<p>鉴于Daocloud的免费服务很不稳定，owncloud镜像每隔几天就要重新启动一次，也就是说每隔几天就要重新配置数据库，虽然数据不会丢失，但是总要配置很烦，所以还是建议大家想要稳定私有云的同志购买付费服务。或者购买vps</p>The post <a href="https://blog.eastonman.com/blog/2017/10/deploy-private-cloud-service-on-daocloud/">在Daocloud上部署私有云</a> first appeared on <a href="https://blog.eastonman.com">Easton Man's Blog</a>.]]></content:encoded>
					
					<wfw:commentRss>https://blog.eastonman.com/blog/2017/10/deploy-private-cloud-service-on-daocloud/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
