<?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>未分类 | Easton Man's Blog</title>
	<atom:link href="https://blog.eastonman.com/blog/category/uncategorized/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.eastonman.com</link>
	<description>临渊羡鱼，不如退而结网</description>
	<lastBuildDate>Wed, 26 Aug 2020 01:07:22 +0000</lastBuildDate>
	<language>zh-Hans</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.5</generator>

<image>
	<url>https://blog.eastonman.com/wp-content/uploads/2021/02/cropped-Logo-e1613298891313-32x32.png</url>
	<title>未分类 | 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></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>本文基于的应用场景是作者个人维护十数台可用性要求不是很高的非生产环i8境服务器（个人博客，团队git服务器等）。</p>



<p>那么这样的应用场景要求选用的系统尽量满足一下特性：</p>



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



<p>目前作者接触到的服务器监控系统大概有那么几个，全部都基于开源软件。传统老牌监控系统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>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>功能强大的同时也相应的会带来重量级的问题，官方文档给出的要求是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>Nagios相比于Zabbix似乎更为的重量级，至少需要1GB的内存和8GB的硬盘来完成一次完整的安装。<br>与Zabbix提供的一体式解决方案不同，Nagios的系统更加组件化，提供给大型企业更大的自定义空间，组件间耦合度较Zabbix低。<br>我自己未安装使用过Nagios，因此不作过多评价。</p>



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



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



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



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



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



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



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



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



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



<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>.]]></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>对于生产环境下php响应缓慢的问题，一般我们可以把分析流程拆分为如下几步操作：</p>



<p>1.分析开发环境下执行是否会慢；</p>



<p>如果是代码问题，在开发环境下就能检测出来；</p>



<p>2.分析测试机器执行是否会慢；</p>



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



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



<p>如果是机器的问题，在这一步才能检查出来。</p>



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



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



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



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



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



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



<p>由于部署环境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>配置php.ini，加入</p>



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



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



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



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



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



<p>因为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>按照提示交互式安装mongodb就行了。‌‌如果你不想这么麻烦或者非生产环境部署，也可以直接使用apt安装：apt install mongodb<code> </code></p>



<p>如果没有在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>同样地，在php.ini中添加extension=mongodb.so<code> </code></p>



<p>官方基于性能建议我们为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>至此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>代码下载完以后上传到网站目录，具体操作因环境而异，若不熟悉请先熟悉lnmp架构。‌‌上传完后执行</p>



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



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



<p>假设我们需要调试的网站位于dev.fqdn‌‌而xhgui位于xhgui.fqdn</p>



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



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



<p>‌                              <code>location / {     try_files $uri $uri/ /index.php?$args; } </code></p>



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



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



<p>‌                              <code>cp &lt;wwwroot>/config/config.default.php &lt;wwwroot>/config/config.php </code></p>



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



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



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



<p>‌ &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>这样一来就只会看到我们希望分析的请求了。</p>



<p>参考：‌‌</p>



<p><a href="https://phperzh.com/articles/3235">phperzh</a>‌‌</p>



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



<p><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>本文将从全栈角度分析typecho性能提升关键，并最终实现首屏时间缩短到1s以内</p>



<p></p>



<p>文中服务器是用的是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>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>php性能直接影响TTFB(首字节时间)，趁早升级吧。</p>



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



<p><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>可以看出，此时php执行已经非常快了，若是在国内或是香港的vps上，TTFB已经可以缩短到通常建议的300ms以下了</p>



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



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



<p>下图是在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>安利一下loader.io，这是一个sendgrid旗下的压力测试工具，免费版最高可以使用美每秒850新链接。</p>



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



<p>实际可以达到的并发数大概在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>一般而言推荐保持和CPU核心数一样，比如2。<br>默认的配置是1，如果在多核服务器上这会导致CPU仅利用一核。<br>也可以配置为auto。</p>



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



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



<p>在Nginx配置的server段监听端口后添加tcpfastopen=3</p>



<p>如</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>同样也有tcpfastopen 设置，开启方法大家google一下</p>



<p>推荐开启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>如果系统默认的文件打开数太小，可以扩大一些<br>比如Ubuntu默认1024，高并发时可能会出现文件打开数过多的错误。<br>使用以下命令</p>



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



<p>可以添加到启动脚本以实现每次开机自动调整nofile限制。</p>



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



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



<p>非异步加载的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>css压缩是用gulp-minify 实现的，在主题发布时已经完成。</p>



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



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



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



<p>非首屏图片懒加载，也就是直到图片进入视野中时才加载图面，这样在加载首屏时就可以节省很多时间。<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>可以看到，在这样的网络延迟下，DOM树加载完毕仅在html下载完成后一百多毫秒，ttfb也是接近网络延迟，服务器处理时间仅有二十几毫秒。这次的性能优化还是很有效果的。</p>



<p>水平有限，如有错误之处欢迎指正。</p>
</div></div>



<p></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/07/uninstall-deepfreeze-without-password/</link>
					<comments>https://blog.eastonman.com/blog/2018/07/uninstall-deepfreeze-without-password/#respond</comments>
		
		<dc:creator><![CDATA[Easton Man]]></dc:creator>
		<pubDate>Mon, 02 Jul 2018 13:55:00 +0000</pubDate>
				<category><![CDATA[未分类]]></category>
		<category><![CDATA[Application]]></category>
		<guid isPermaLink="false">https://blog.eastonman.com/2018/07/02/uninstall-deepfreeze-without-password/</guid>

					<description><![CDATA[<p>预计阅读时间： 1 分钟 冰点DeepFreeze是一款系统还原软件，可以防止病毒和恶意软件更改系统。冰点的权 [&#8230;]</p>
The post <a href="https://blog.eastonman.com/blog/2018/07/uninstall-deepfreeze-without-password/">绕过密码卸载冰点</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>冰点DeepFreeze是一款系统还原软件，可以防止病毒和恶意软件更改系统。冰点的权限非常高，是SYSTEM,普通的方法对它无效，下面介绍一种可以绕过密码卸载冰点还原的办法。</p>
<p>前提:你可以操作机器的BIOS并选择引导顺序</p>
<h2 id="-persi0-sys-">获取Persi0.sys配置文件</h2>
<p>提供一个7.3版本的<br /><a href="https://get.bash.moe/deepfreeze/Persi0.sys">Persi0.sys</a><br />更加通用的做法是找一台机器装一个一样版本的未启用还原的冰点Persi0.sys配置文件</p>
<p>Persi0.sys是冰点的配置文件，在C:\下</p>
<p>而如果我们正常进入系统，冰点的SYSTEM权限会使得没有人能读取或者写入这个文件(除非采用非常手段提权至SYSTEM)<br />所以我们要避开windows的权限限制</p>
<h2 id="-u-">从U盘启动</h2>
<p>找一个可以启动的U盘，里面可以是Ubuntu安装盘，WinPE启动盘，甚至是Win10 OTG都可以<br />只要将上一步中的Persi0.sys复制到C:\下，再进入系统，就会发现冰点还原被关闭了，若是复制的配置文件是已知密码的，这时密码也一并知道了。</p>
<p>解除还原保护以后就可以正常卸载冰点了。<br />卸载的方法是再次打开安装所用的exe文件，安装文件会检测安装情况并提供卸载选项。</p>The post <a href="https://blog.eastonman.com/blog/2018/07/uninstall-deepfreeze-without-password/">绕过密码卸载冰点</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/uninstall-deepfreeze-without-password/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>[翻译]Github替代品</title>
		<link>https://blog.eastonman.com/blog/2018/06/github-alternatives/</link>
					<comments>https://blog.eastonman.com/blog/2018/06/github-alternatives/#respond</comments>
		
		<dc:creator><![CDATA[Easton Man]]></dc:creator>
		<pubDate>Fri, 08 Jun 2018 16:47:00 +0000</pubDate>
				<category><![CDATA[未分类]]></category>
		<category><![CDATA[Translation]]></category>
		<guid isPermaLink="false">https://blog.eastonman.com/2018/06/08/github-alternatives/</guid>

					<description><![CDATA[<p>预计阅读时间： 6 分钟 不久前的热门消息是[微软](https://news.microsoft.com/2 [&#8230;]</p>
The post <a href="https://blog.eastonman.com/blog/2018/06/github-alternatives/">[翻译]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">预计阅读时间： 6 分钟</p>
<p>不久前的热门消息是[微软](https://news.microsoft.com/2018/06/04/microsoft-to-acquire-github-for-7-5-billion/)[收购了Github](https://blogs.microsoft.com/blog/2018/06/04/microsoft-github-empowering-developers/)（全球领先的软件开发平台）。 对于微软来说，这可能会让它回到在软件市场10年前的地位，但是，很多开源粉丝对此感到很不满。</p>



<h1 class="wp-block-heading" id="github-">Github的替代品（免费、付费、自建）</h1>



<p>几年前，微软是反开源的。</p>



<figure class="wp-block-image kg-card kg-image-card"><img decoding="async" src="/content/images/2019/10/17325329.png" alt="Jim-Allchin-Open-Source.png"/></figure>



<p>“开源是一个知识产权破坏者。我无法想象有什么比这对于软件业务和知识产权业务来说更糟糕。“ &#8211; Jim Allchin（前Windows总裁），2001年</p>



<figure class="wp-block-image kg-card kg-image-card"><img decoding="async" src="/content/images/2019/10/1570606624.png" alt="Steve-Balmer-Linux-Cancer.png"/></figure>



<p>“Linux是一种癌症，它把它自己附着在任何它能触碰得到的知识产权产物上” &#8211; 史蒂夫鲍尔默（前首席执行官）</p>



<p>然而，近年来，微软正努力赶上开源世界的脚步。<br>他们正在推动自己成为开源的支持者。<br>他们已经开源了他们的一些<a href="https://opensource.microsoft.com/">项目</a>，并且还以白金会员的身份加入了<a href="https://www.zdnet.com/article/microsoft-completes-its-linux-journey-joins-the-linux-foundation/">The Linux Foundation</a>。</p>



<figure class="wp-block-image kg-card kg-image-card"><img decoding="async" src="/content/images/2019/10/614763767.png" alt="MS-loves-Linux.png"/></figure>



<p>没有人知道他们是否这样做是因为他们接受并认同开源，还是他们只是试图通过吸引开源用户的注意力而维持业务。<br>这当然会带来信任问题。<br>一些GitHub用户已经开始寻找Github的替代品了。</p>



<p>以下是一些类似于GitHub的热门服务列表：</p>



<h2 class="wp-block-heading" id="1-gitlab">1. <a href="https://about.gitlab.com/">Gitlab</a></h2>



<p>社交媒体上的大多数用户似乎都选择<a href="https://about.gitlab.com/">Gitlab</a>作为GitHub的替代品。</p>



<figure class="wp-block-image kg-card kg-image-card"><img decoding="async" src="/content/images/2019/10/2208925451.png" alt="GitLab"/></figure>



<h3 class="wp-block-heading" id="-">特性：</h3>



<ul class="wp-block-list"><li>issue版，issue跟踪（含有截止日期）</li><li>内置CI / CD</li><li>无限的私有仓库</li><li>更快的文件搜索</li><li>Cherry pick</li><li>文件锁定</li><li>Web IDE</li><li>项目wiki</li><li>无广告</li><li>代码审查和pull requests支持评论</li><li>静态/动态应用安全测试，Docker容器扫描</li><li>智能镜像加快clone，fetch，pull（高级功能）</li><li>托管静态网站</li></ul>



<figure class="wp-block-image kg-card kg-image-card"><img decoding="async" src="/content/images/2019/10/533997496.png" alt="GitLab-Features.png"/></figure>



<p>GitLab的统计数据显示，在过去几个小时内从GitHub导入了大量仓库。</p>



<h2 class="wp-block-heading" id="2-bitbucket">2. <a href="https://bitbucket.org/">BitBucket</a></h2>



<p>一个Atlassian旗下的产品，是GitHub最受欢迎的替代产品之一。</p>



<h3 class="wp-block-heading" id="--1">特性：</h3>



<ul class="wp-block-list"><li>无限的私有仓库</li><li>JIRA集成</li><li>双因子认证</li><li>LFS支持</li><li>源代码搜索</li><li>项目wiki</li><li>issue追踪</li><li>无广告</li><li>代码审查和pull requests支持评论</li><li>用于托管静态网站的BitBucket云（类似于GitHub页面）</li><li>智能镜像加快clone，fetch，pull(高级功能)</li></ul>



<figure class="wp-block-image kg-card kg-image-card"><img decoding="async" src="/content/images/2019/10/3720479030.png" alt="BitBucket-features.png"/></figure>



<h3 class="wp-block-heading" id="--2">价格:</h3>



<figure class="wp-block-image kg-card kg-image-card"><img decoding="async" src="/content/images/2019/10/850599048.png" alt="BitBucket-pricing.png"/></figure>



<h3 class="wp-block-heading" id="bitbucket-datacentre-github-enterprise-">BitBucket DataCentre 和 Github Enterprise 对比</h3>



<figure class="wp-block-image kg-card kg-image-card"><img decoding="async" src="/content/images/2019/10/2777638106.png" alt="BitBucket-vs-GitHub.png"/></figure>



<h2 class="wp-block-heading" id="3-gitea">3. <a href="https://gitea.io/en-US/">Gitea</a></h2>



<p>用Go语言编写的轻量级GitHub仿制版本（由GoGs fork出）。</p>



<h3 class="wp-block-heading" id="--3">特性：</h3>



<ul class="wp-block-list"><li>GitHub翻版</li><li>运行在Windows，Mac和Linux上</li><li>轻量级（甚至支持树莓派）</li><li>从二进制安装</li><li>可以从Docker，Vargrant包管理器安装</li><li>仓库查看器</li><li>issue跟踪器</li><li>项目wiki</li><li>API支持</li><li>帮助（支持论坛和聊天）</li></ul>



<figure class="wp-block-image kg-card kg-image-card"><img decoding="async" src="/content/images/2019/10/75850149.png" alt="gitea.png"/></figure>



<h2 class="wp-block-heading" id="4-sourceforge">4. <a href="https://sourceforge.net/">SourceForge</a></h2>



<p>一个最早（从1999年开始）为开源项目提供免费服务的网站之一。</p>



<h3 class="wp-block-heading" id="--4">特性：</h3>



<ul class="wp-block-list"><li>issue跟踪</li><li>代码托管</li><li>镜像</li><li>wiki</li><li>邮件列表</li><li>支持论坛</li><li>用户对项目的评论</li><li>项目的微博客</li><li>无限带宽</li><li>下载统计</li><li><a href="https://sourceforge.net/p/forge/documentation/GitHub%20Importer/">导入GitHub项目的工具</a></li></ul>



<figure class="wp-block-image kg-card kg-image-card"><img decoding="async" src="/content/images/2019/10/1026469625.png" alt="sourceforge-features.png"/></figure>



<h2 class="wp-block-heading" id="5-launchpad">5. <a href="https://launchpad.net/">Launchpad</a></h2>



<p>一款来自Canonical的产品，因托管Ubuntu项目而闻名。</p>



<h3 class="wp-block-heading" id="--5">特性：</h3>



<ul class="wp-block-list"><li>issue跟踪</li><li>代码托管（支持Git和Bazaar）</li><li>代码评论</li><li>构建和托管Ubuntu项目</li><li>邮件列表</li><li>翻译</li><li>常见问题解答</li><li>规范跟踪</li></ul>



<figure class="wp-block-image kg-card kg-image-card"><img decoding="async" src="/content/images/2019/10/3094470639.png" alt="launchpad-features.png"/></figure>



<h2 class="wp-block-heading" id="6-cloud-source-repositories-">6. <a href="https://cloud.google.com/source-repositories/">Cloud Source Repositories</a> (付费)</h2>



<p>这个来自Google的产品是Google Cloud的一部分。</p>



<h3 class="wp-block-heading" id="--6">特性：</h3>



<ul class="wp-block-list"><li>将您的仓库从BitBucket或GitHub连接起来</li><li>源代码浏览器</li><li>调试和错误报告工具</li><li>稳定且易于扩展的基础架构</li><li>通过容器构建的CI</li><li>预安装的工具（编程语言，云命令行和Shell编辑器）</li><li>通过App Engine加快部署</li><li>通过自定义触发器进行部署（HTTP，Pub / Sub等）</li></ul>



<figure class="wp-block-image kg-card kg-image-card"><img decoding="async" src="/content/images/2019/10/3581545737.png" alt="cloud-source-repo-features.png"/></figure>



<h3 class="wp-block-heading" id="--7">价格:</h3>



<figure class="wp-block-image kg-card kg-image-card"><img decoding="async" src="/content/images/2019/10/693164311.png" alt="cloud-source-repo.png"/></figure>



<h2 class="wp-block-heading" id="7-aws-codecommit-">7. <a href="https://aws.amazon.com/codecommit/">AWS CodeCommit</a> (付费)</h2>



<p>该产品与Cloud Source Repo类似，如果您已拥有AWS账户，您可以免费获得它（每月最多5个用户）。</p>



<h3 class="wp-block-heading" id="--8">特性：</h3>



<ul class="wp-block-list"><li>托管在AWS上</li><li>加密存储库</li><li>代码审查和pull requests支持评论</li><li>可扩展</li><li>数据的大小或类型没有限制</li><li>轻松从其他服务迁移</li></ul>



<figure class="wp-block-image kg-card kg-image-card"><img decoding="async" src="/content/images/2019/10/1606549063.png" alt="aws-codecommit-features.png"/></figure>



<h3 class="wp-block-heading" id="--9">价格:</h3>



<figure class="wp-block-image kg-card kg-image-card"><img decoding="async" src="/content/images/2019/10/1339741042.png" alt="aws-commit.png"/></figure>



<h2 class="wp-block-heading" id="8-phabricator-">8. <a href="https://phacility.com/phabricator/">Phabricator</a> (付费或自建)</h2>



<h3 class="wp-block-heading" id="--10">特性：</h3>



<ul class="wp-block-list"><li>源代码托管</li><li>Git，Mercurial，SVN支持</li><li>代码审查和审计</li><li>wiki</li><li>问题跟踪器</li><li>工作板</li><li>聊天频道</li><li>命令行工具（lint，单元测试）</li><li>API支持</li></ul>



<figure class="wp-block-image kg-card kg-image-card"><img decoding="async" src="/content/images/2019/10/1420699508.png" alt="Phabricator.png"/></figure>



<h3 class="wp-block-heading" id="--11">价格:</h3>



<figure class="wp-block-image kg-card kg-image-card"><img decoding="async" src="/content/images/2019/10/192999450.png" alt="phabricator-pricing.png"/></figure>



<h2 class="wp-block-heading" id="9-gitbucket-">9. <a href="https://gitbucket.github.io">GitBucket</a> (自建)</h2>



<p>JVM上的git平台。</p>



<h3 class="wp-block-heading" id="--12">特性：</h3>



<ul class="wp-block-list"><li>用Scala支持</li><li>高度可扩展性</li><li>GitHub API兼容</li><li>仓库查看器</li><li>issue跟踪器</li><li>wiki</li><li>插件支持</li></ul>



<figure class="wp-block-image kg-card kg-image-card"><img decoding="async" src="/content/images/2019/10/2008543672.png" alt="GitBucket.png"/></figure>



<h2 class="wp-block-heading" id="10-gogs-">10. <a href="https://gogs.io/">GoGs</a> (自建)</h2>



<p>用Go编写的易于安装和轻量级的GitHub仿制版。</p>



<h3 class="wp-block-heading" id="--13">特性：</h3>



<ul class="wp-block-list"><li>GitHub翻版</li><li>从二进制安装</li><li>从Docker,Vargrant包管理器安装</li><li>跨平台支持</li><li>轻量级（运行在树莓派上）</li><li>仓库查看器</li><li>issue跟踪器</li><li>wiki</li></ul>



<figure class="wp-block-image kg-card kg-image-card"><img decoding="async" src="/content/images/2019/10/700190758.png" alt="GoGs.png"/></figure>



<h1 class="wp-block-heading" id="11-gitprep-">11. <a href="http://gitprep.yukikimoto.com">GitPrep</a> (自建)</h1>



<p>用Perl编写的GitHub仿制版本。</p>



<h3 class="wp-block-heading" id="--14">特性：</h3>



<ul class="wp-block-list"><li>GitHub翻版</li><li>绿色(无需安装)</li><li>issue跟踪器</li><li>CGI支持</li><li>内置Web服务器</li><li>SSL支持</li><li>公钥认证支持</li></ul>



<figure class="wp-block-image kg-card kg-image-card"><img decoding="async" src="/content/images/2019/10/3544067222.png" alt="gitprep.png"/></figure>



<h2 class="wp-block-heading" id="12-allura-">12. <a href="https://allura.apache.org">Allura</a> (自建)</h2>



<p>一个来自Apache的产品。<br>Sourceforge就运行在Allura上。</p>



<h3 class="wp-block-heading" id="--15">特性：</h3>



<ul class="wp-block-list"><li>代码仓库</li><li>支持Git，Mercurial，SVN</li><li>issue tracker</li><li>讨论论坛</li><li>wiki</li><li>邮件列表</li></ul>



<p>你更青睐哪个Github的替代品？在留言中告诉我吧。</p>



<p>原文地址(English):<a href="https://tutswiki.com/github-alternatives/">Github Alternatives</a></p>The post <a href="https://blog.eastonman.com/blog/2018/06/github-alternatives/">[翻译]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/06/github-alternatives/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>FontCustom生成font-face字体图标</title>
		<link>https://blog.eastonman.com/blog/2018/02/fontcustomsheng-cheng-font-facezi-ti-tu-biao/</link>
					<comments>https://blog.eastonman.com/blog/2018/02/fontcustomsheng-cheng-font-facezi-ti-tu-biao/#respond</comments>
		
		<dc:creator><![CDATA[Easton Man]]></dc:creator>
		<pubDate>Fri, 09 Feb 2018 02:59:00 +0000</pubDate>
				<category><![CDATA[未分类]]></category>
		<category><![CDATA[Frontend]]></category>
		<guid isPermaLink="false">https://blog.eastonman.com/2018/02/09/fontcustomsheng-cheng-font-facezi-ti-tu-biao/</guid>

					<description><![CDATA[<p>预计阅读时间： 2 分钟 这几天把页面底部的sns图标加进New Material主题，发现原作者是直接用pn [&#8230;]</p>
The post <a href="https://blog.eastonman.com/blog/2018/02/fontcustomsheng-cheng-font-facezi-ti-tu-biao/">FontCustom生成font-face字体图标</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>这几天把页面底部的sns图标加进New Material主题，发现原作者是直接用png做 <code>&lt;button&gt;</code> 的背景图，这样的话有几个缺点，一是png放大了一以后会不清楚（虽然改用svg也能解决），二是要写太多自定义的css了，可移植性差，这也是最主要的一点（我懒，嘻嘻嘻），还有就是html里标签又div又a又button又span的，可读性也差。作为一个完美主义者，我怎么能容忍这样的结构呢，于是我果断加入@font-face方式的图标。</p>
<h1 id="-font-face-">什么是font-face字体图标</h1>
<p>unicode编码（也叫utf-8）除了正常的字符以外，<code>\e000</code> 开始的一段是空的，也就是留给自造字用。如果把图标放到这一段呢？这就是字体图标的原理，字体在css里类是@font-face，所以又叫font-face图标。</p>
<h1 id="fontcustom">Fontcustom</h1>
<p>说了那么多，到底Fontcustom是什么呢？</p>
<p><a href="https://github.com/fontcustom/fontcustom">Fontcustom Github</a></p>
<p>Fontcustom是一个基于rubygems的工具，帮助个位开发者把svg图片转成@font-face需要的字体格式，也生成好所需的css，要用时只需外链一个css就可以了。</p>
<h1 id="-fontcustom">安装fontcustom</h1>
<h2 id="-rubygems">安装rubygems</h2>
<p>其实主要麻烦之处在于rubygems的安装，除了有一些坑以外，别的应该没有什么难度</p>
<p>ubuntu 16.04</p>
<pre><code>apt install ruby ruby-dev 
</code></pre>
<p>ubuntu 14.04</p>
<pre><code>apt install ruby rubygems
</code></pre>
<h2 id="-fontcustom-1">安装Fontcustom</h2>
<p>Fontcustom要求安装好 Ruby 1.9.3+, WOFF2, FontForge</p>
<p>安装依赖</p>
<pre><code># On Mac
brew tap bramstein/webfonttools
brew update
brew install woff2

brew install fontforge --with-python
brew install eot-utils
gem install fontcustom

# On Linux
sudo apt-get install zlib1g-dev fontforge
git clone https://github.com/bramstein/sfnt2woff-zopfli.git sfnt2woff-zopfli &amp;&amp; cd sfnt2woff-zopfli &amp;&amp; make &amp;&amp; mv sfnt2woff-zopfli /usr/local/bin/sfnt2woff
git clone --recursive https://github.com/google/woff2.git &amp;&amp; cd woff2 &amp;&amp; make clean all &amp;&amp; sudo mv woff2_compress /usr/local/bin/ &amp;&amp; sudo mv woff2_decompress /usr/local/bin
</code></pre>
<p>安装fontcustom</p>
<pre><code>gem install fontcustom
</code></pre>
<p>大功告成！<br />安装过程可能出现<br />gems报错<br />Cannot Compile Extension ffi<br />或者之类的</p>
<p>这是由于apt安装的rubygems要自行编译所有extension</p>
<p>安装libffi就可以了</p>
<pre><code>apt install libffi-dev
</code></pre>
<h1 id="fontcustom-">Fontcustom 简单使用</h1>
<pre><code>fontcustom compile my/vectors  # 生成到 `fontcustom/`
fontcustom watch my/vectors    # 监视my/vectors的文件改变，即时生成
fontcustom compile             # 使用默认的配置文件 ./fontcustom.yml
fontcustom config              # 生成空白的配置文件
fontcustom help                # 查看所有用法
</code></pre>
<p>啊哈！简直太方便了</p>The post <a href="https://blog.eastonman.com/blog/2018/02/fontcustomsheng-cheng-font-facezi-ti-tu-biao/">FontCustom生成font-face字体图标</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/02/fontcustomsheng-cheng-font-facezi-ti-tu-biao/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
