<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>后端开发 on Foam 的博客</title>
    <link>https://blog.foamzou.com/categories/%E5%90%8E%E7%AB%AF%E5%BC%80%E5%8F%91/</link>
    <description>Recent content in 后端开发 on Foam 的博客</description>
    <generator>Hugo</generator>
    <language>zh-cn</language>
    <lastBuildDate>Sun, 30 Aug 2020 00:07:46 +0800</lastBuildDate>
    <atom:link href="https://blog.foamzou.com/categories/%E5%90%8E%E7%AB%AF%E5%BC%80%E5%8F%91/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Best Practices for using Lambda@Edge to process images on AWS</title>
      <link>https://blog.foamzou.com/posts/best-practices-for-using-lambdaedge-to-process-images-on-aws-en/</link>
      <pubDate>Sun, 30 Aug 2020 00:07:46 +0800</pubDate>
      <guid>https://blog.foamzou.com/posts/best-practices-for-using-lambdaedge-to-process-images-on-aws-en/</guid>
      <description>&lt;h2 id=&#34;github&#34;&gt;Github&lt;/h2&gt;
&lt;p&gt;Provides docker environment and code which process image. Welcome to star, fork or PR to improve the practice. Repo：&lt;a href=&#34;https://github.com/foamzou/aws-lambda-edge-image-process&#34;&gt;Click The Link&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;whats-this&#34;&gt;What&amp;rsquo;s this&lt;/h2&gt;
&lt;p&gt;For the same image link, we may response different sizes of thumbnails according to different pages. Unfortunately, AWS does not directly provide such services. But it provides lambda@edge with CloudFront to handle this kind of demand. Therefore, I designed a set of solutions to achieve the requirements of image processing. This article contains instructions, design solutions and practical steps.&lt;/p&gt;</description>
    </item>
    <item>
      <title>在AWS使用Lambda@Edge处理图片的最佳实践</title>
      <link>https://blog.foamzou.com/posts/best-practices-for-using-lambdaedge-to-process-images-on-aws/</link>
      <pubDate>Sun, 30 Aug 2020 00:07:14 +0800</pubDate>
      <guid>https://blog.foamzou.com/posts/best-practices-for-using-lambdaedge-to-process-images-on-aws/</guid>
      <description>&lt;h2 id=&#34;github&#34;&gt;Github&lt;/h2&gt;
&lt;p&gt;提供了docker环境和简单的图片处理代码；欢迎star、fork或提交pr以改善该实践。仓库：&lt;a href=&#34;https://github.com/foamzou/aws-lambda-edge-image-process&#34;&gt;点我&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;这是什么&#34;&gt;这是什么&lt;/h2&gt;
&lt;p&gt;类似阿里云OSS的图片处理服务、腾讯云的数据万象。&lt;/p&gt;
&lt;p&gt;因为AWS并没有单独将图片处理单独发布服务，只提供了lambda配合CloudFront用于处理这类需求。因此我设计了一套方案用于实现图片处理的需求，本文档包含使用说明、设计方案。&lt;/p&gt;
&lt;p&gt;有了本方案，前端可以在原有的cdn图片链接后面拼接参数，获取对应的缩略图、加水印等图片处理需求。&lt;/p&gt;
&lt;h2 id=&#34;本方案涉及到的几个角色&#34;&gt;本方案涉及到的几个角色&lt;/h2&gt;
&lt;h3 id=&#34;cloudfront&#34;&gt;CloudFront&lt;/h3&gt;
&lt;p&gt;Amazon的CDN服务，在本方案用于缓存缩略图。下面简称CF&lt;/p&gt;
&lt;h3 id=&#34;lambdaedge&#34;&gt;Lambda@edge&lt;/h3&gt;
&lt;p&gt;Lambda是Amazon的云函数，就是serverless那一套。&lt;/p&gt;
&lt;p&gt;Lambda@edge则是可以运行在CloudFront边缘的函数，比Lambda支持的能力要弱一些。例如runtime只支持Node.js和Python；不支持Layer，导致使用的图片库无法部署在layer，只能全部打包到源码。&lt;/p&gt;
&lt;p&gt;对图片的处理逻辑在这一层运行，是本方案的重点对象。下面简称Lambda&lt;/p&gt;
&lt;h3 id=&#34;s3&#34;&gt;S3&lt;/h3&gt;
&lt;p&gt;Amazon的对象存储服务，类似阿里的OSS。在本方案扮演 存储原图、缩略图；cdn回源的角色&lt;/p&gt;
&lt;h2 id=&#34;工作流程&#34;&gt;工作流程&lt;/h2&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://blog.foamzou.com/posts/best-practices-for-using-lambdaedge-to-process-images-on-aws/image-3-1024x434.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;Image Generate WOrkflow&lt;/p&gt;
&lt;p&gt;注意：只有在CF行为规则配置了规则（例如 &lt;strong&gt;.jpg@&lt;/strong&gt; ），才会触发lambda。直接访问原图的不经过lambda，不必担心过度计费问题。&lt;/p&gt;
&lt;p&gt;请参考上图，流程为：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;步骤0：用户请求图片链接：链接形如：&lt;strong&gt;&lt;a href=&#34;http://cdn.com/image/abc.jpg@250w&#34;&gt;http://cdn.com/image/abc.jpg@250w&lt;/a&gt;_60q.webp&lt;/strong&gt;。其中 http://cdn.com/image/abc.jpg 是原图链接，@后面是处理参数，具体含义请参看使用手册&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;步骤1：请求先到达CF，检查CF有缓存则直接返回给用户，并且etag与客户端一致时响应304 Not Modified&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;步骤2：若CF未命中，则回源到S3获取图片。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;步骤3：S3响应后，CF事件会触发给lambda，函数逻辑会对response进行判断：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果http code为正常值，说明缩略图在S3已存在，那么不进行其它处理，直接将response返回&lt;/li&gt;
&lt;li&gt;步骤5：如果http code为异常值，说明S3没有该图，我们需要做以下处理：
&lt;ul&gt;
&lt;li&gt;将URI从@开始剥离，前面的为&lt;strong&gt;原图KEY&lt;/strong&gt;，后面的为&lt;strong&gt;处理参数&lt;/strong&gt;。我们使用原图KEY从S3桶（CF事件的request链接可以提取到桶名）获取原图，然后使用处理参数对图片进行处理。这里使用sharp图片处理库(底层使用libvips，比ImageMagic性能要好)。&lt;/li&gt;
&lt;li&gt;将处理好的图片存储到S3，以便下次CF失效时，直接回源到S3获取。这里存储到S3时，给图片打了标签（createByLambda:1），方便在S3根据标签制定淘汰规则，避免过多缩略图长期存在S3造成浪费。&lt;/li&gt;
&lt;li&gt;将图片以base64编码返回到CF，content-encoding为base64。这里之所以使用base64是因为lambda只支持接收json&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;步骤4：CF将源头的图片存储起来并响应给用户&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;前端使用说明&#34;&gt;前端使用说明&lt;/h2&gt;
&lt;p&gt;url构成：https://cdn域名/文件名@&amp;lt;参数值1&amp;gt;&amp;lt;参数名1&amp;gt;_&amp;lt;参数值2&amp;gt;&amp;lt;参数名2&amp;gt;.期望转换的文件格式&lt;/p&gt;
&lt;p&gt;例子：https://d1xxxxxxxx.cloudfront.net/foamzou/image/4951f0e35a37e5190e78798dcfcad984.jpg@1020w_160h_0e_1l_70q.webp&lt;/p&gt;
&lt;h3 id=&#34;参数&#34;&gt;参数&lt;/h3&gt;
&lt;p&gt;w: 指定目标缩略图的宽度。1-4096&lt;/p&gt;
&lt;p&gt;h: 指定目标缩略图的高度。1-4096&lt;/p&gt;
&lt;p&gt;e: 缩放优先边。0：长边优先，1：短边优先，2：强制按指定宽高缩放。默认为0&lt;/p&gt;
&lt;p&gt;l: 目标缩略图大于原图是否处理。如果值是1, 即不处理；是0，表示处理。默认为0&lt;/p&gt;
&lt;p&gt;p: 比例百分比。 小于100，即是缩小，大于100即是放大。1-1000。如果参数p跟w、h合用时，p将直接作用于w、h （乘以p%）得到新的w、h，例如100w_100h_200p的作用跟200w_200h的效果是一样的。默认为100&lt;/p&gt;
&lt;p&gt;q: 质量百分比。1-100。默认为80&lt;/p&gt;
&lt;p&gt;r: 是否使用渐进式jpeg。0：不使用，1使用。默认为0。只有在输出格式为jpg时，该参数才会生效。注意：1. 小尺寸图片不建议使用，因为渐进式jpeg会比原图大；2. 能够使用webp尽量使用webp；3. 渐进式展示图片的最佳方案应当是前端同时渲染小图和大图，动画过度到大图&lt;/p&gt;
&lt;p&gt;.format 格式转换。目前支持jpg, png, webp。若保留原文件格式，那么  .format 可以不添加&lt;/p&gt;</description>
    </item>
    <item>
      <title>使用netcat能够做什么</title>
      <link>https://blog.foamzou.com/posts/what-can-netcat-do/</link>
      <pubDate>Mon, 11 May 2020 15:46:36 +0800</pubDate>
      <guid>https://blog.foamzou.com/posts/what-can-netcat-do/</guid>
      <description>&lt;h2 id=&#34;楔子&#34;&gt;楔子&lt;/h2&gt;
&lt;p&gt;[admonition] 今天朋友找我解决一个问题，他的java服务在阿里服务器里监听了某端口（使用的TCP），但通过公网无法连接。我尝试在本地telnet那个端口（跨公网），不通。在他服务器里telnet 127.0.0.1 端口，是通的。说明服务正常监听了端口。但由于我不熟悉他的java服务，无法判断该java服务是否只监听了本地回环地址。 因此公网无法访问大概有两种可能，一，java服务只监听了本地回环地址； 二、防火墙限制了端口 排除第二种情况对我来说比较简单，我通过netcat在服务器监听端口，然后在本地telnet，不通！说明问题的确出在防火墙身上。该服务器为Ubuntu，使用&lt;code&gt;ufw status&lt;/code&gt;查看防火墙状态，显示为&lt;code&gt;inactive&lt;/code&gt;，也就是关闭状态。再查看阿里云安全组规则，已经开放了tcp/udp的所有端口(-1/-1)。后面我再次执行&lt;code&gt;ufw disable&lt;/code&gt;，端口就通了。所以这是ufw的bug？ [/admonition] 引子有点长了。主要是为了说明，如果想知道与服务器之间的tcp连接是否通，可以使用netcat工具去判断。下面介绍下netcat ~&lt;/p&gt;
&lt;h2 id=&#34;netcat是什么&#34;&gt;netcat是什么&lt;/h2&gt;
&lt;p&gt;是一种计算机网络实用程序，用于使用TCP或UDP读写网络连接，号称 TCP/IP 的瑞士军刀。大家一般简写为&lt;code&gt;nc&lt;/code&gt;。总之，涉及到网络的事儿，它几乎都能做。为什么叫瑞士军刀，因为它体积很小，不同版本的nc可执行文件只有几十k到300多k，而且大部分linux发行版都有预安装。&lt;/p&gt;
&lt;h2 id=&#34;各种版本&#34;&gt;各种版本&lt;/h2&gt;
&lt;p&gt;netcat有许多版本，能力从弱到强为：GUN、BSD、Ncat。基础功能三者都一样，不同的是一些版本额外内置了些高级/有趣的功能（例如Ncat有个参数&lt;code&gt;--chat&lt;/code&gt;，可以创建匿名聊天室）。 大部分centos6内置的是BSD版本的nc，我的Centos7里边内置的nc是Ncat（属于nmap工具集里边） 使用&lt;code&gt;man nc&lt;/code&gt;，拉到最下边可以看到你的nc版本。（使用man你基本能够查阅所有的用法了，其它软件也是如此，只要是标准安装的） ps. socat号称是更为强大的nc，有兴趣的小伙伴可以自己去看看。&lt;/p&gt;
&lt;h2 id=&#34;用途&#34;&gt;用途&lt;/h2&gt;
&lt;h3 id=&#34;检查端口通不通&#34;&gt;检查端口通不通&lt;/h3&gt;
&lt;p&gt;以往我一直使用telnet来判断某个端口是否通，但telnet是基于tcp协议的，如果要判断udp端口就无能为力了。这时可以使用nc来判断。为了方便实验，本文统一使用同一台机器模拟服务端和客户端。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;# 咱们使用nc创建一个tcp协议监听的端口。-l为listen，默认协议为tcp
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;nc -l 8088
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;# 使用nc连上该端口。-v(verbose)用于显示更多信息，-z（zero I/O）表示不发送数据包，仅显示连接状态。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;# 下面succeed表示端口是通的
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;nc -vz 127.0.0.1 8088
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Connection to 127.0.0.1 8088 port [tcp/radan-http] succeeded!
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;# 创建一个udp端口。-u指使用udp协议
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;nc -lu 8088
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;# 同样，加一个u表示使用udp连接该端口，同时你会看到服务端打印出若干个X。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;# 不是说加了z参数就不会发数据包吗，为什么服务端收到了报文？我认为udp是无连接状态的，通过系统调用write
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;# 往该套接字发数据，通过返回值才知道包发出去没有，从而判断udp端口是否通
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;nc -vzu 127.0.0.1 8088
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Connection to 127.0.0.1 8088 port [udp/radan-http] succeeded!
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;端口扫描&#34;&gt;端口扫描&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;# 扫描tcp端口。-w(wait)指定连接超时时间，单位秒。
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;# 连接成功的端口将作为标准输出
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;nc -v -w3 -z 127.0.0.1 1-65535 | tee succeed_port.log
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;# 下面摘抄部分连接成功的端口
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; Connection to 127.0.0.1 22 port [tcp/ssh] succeeded!
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; Connection to 127.0.0.1 25 port [tcp/smtp] succeeded!
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; Connection to 127.0.0.1 80 port [tcp/http] succeeded!
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; Connection to 127.0.0.1 443 port [tcp/https] succeeded!
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; Connection to 127.0.0.1 1100 port [tcp/mctp] succeeded!
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; Connection to 127.0.0.1 1111 port [tcp/lmsocialserver]
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; succeeded! Connection to 127.0.0.1 2255 port [tcp/vrtp]
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; succeeded! Connection to 127.0.0.1 3001 port [tcp/*]
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; succeeded! Connection to 127.0.0.1 3306 port [tcp/mysql]
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; succeeded! Connection to 127.0.0.1 4300 port [tcp/corelccam] succeeded!
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; Connection to 127.0.0.1 4369 port [tcp/epmd] succeeded!
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; Connection to 127.0.0.1 5672 port [tcp/amqp] succeeded!
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; Connection to 127.0.0.1 6553 port [tcp/*] succeeded!
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;# 扫描udp端口。nc -v -zu 127.0.0.1 1-65535
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;# 以下为我本地扫描结果
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Connection to 127.0.0.1 636 port [udp/ldaps] succeeded!
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Connection to 127.0.0.1 35157 port [udp/*] succeeded!
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Connection to 127.0.0.1 54890 port [udp/*] succeeded!
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;文件传输&#34;&gt;文件传输&lt;/h3&gt;
&lt;p&gt;归根到底都是创建一个tcp/udp连接，通过连接收发数据而已。所以，无论数据是ascii字符串，二进制文件都可以发送/接收。 为了加快传输速率/加密，你甚至还可以在发送之前对数据进行压缩/加密。 对于大文件，个人认为还是scp、rsync这类专业的工具靠谱。小文件可以试试这种方法，毕竟简单，不需要ssh认证。&lt;/p&gt;</description>
    </item>
    <item>
      <title>恢复数据库快照xb文件到新实例</title>
      <link>https://blog.foamzou.com/posts/recover-snapshot-xb-file-to-mysql-new-instance/</link>
      <pubDate>Wed, 29 Apr 2020 20:37:28 +0800</pubDate>
      <guid>https://blog.foamzou.com/posts/recover-snapshot-xb-file-to-mysql-new-instance/</guid>
      <description>&lt;h2 id=&#34;背景&#34;&gt;背景&lt;/h2&gt;
&lt;p&gt;背景就是我把线上某张表的某个字段给清空了。用的是腾讯云的数据库实例，运维配置的快照是每天早上备份一次，因此可以通过快照文件恢复数据。直接恢复到线上实例是不现实的，所以想法是将快照恢复到本地实例，然后用脚本/工具把数据导出来，再写入线上实例。当时恢复过程比较曲折，这里记录下比较好的操作步骤。&lt;/p&gt;
&lt;h2 id=&#34;获取xb文件&#34;&gt;获取xb文件&lt;/h2&gt;
&lt;p&gt;从云服务商或你自行备份的xb文件中获取。腾讯云 &lt;a href=&#34;https://console.cloud.tencent.com/cdb/backup&#34;&gt;这里&lt;/a&gt; 可找到备份列表&lt;/p&gt;
&lt;h2 id=&#34;安装xbstream和qpress工具&#34;&gt;安装xbstream和qpress工具&lt;/h2&gt;
&lt;p&gt;腾讯云使用qpress压缩文件，再通过xbsteam打包为xb文件。[参考腾讯云&lt;a href=&#34;https://cloud.tencent.com/document/product/236/33363&#34;&gt;文章&lt;/a&gt;]&lt;/p&gt;
&lt;h3 id=&#34;安装xbstream&#34;&gt;安装xbstream&lt;/h3&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;下载并安装 XtraBackup 工具。 下载地址请参见 &lt;a href=&#34;https://www.percona.com/downloads/Percona-XtraBackup-2.4/LATEST/&#34;&gt;Percona XtraBackup 官网&lt;/a&gt;，请选择 Percona XtraBackup 2.4.6 及以上的版本，安装介绍请参见 &lt;a href=&#34;https://www.percona.com/doc/percona-xtrabackup/2.4/installation.html?spm=a2c4g.11186623.2.14.4d8653a6QmHkgI&#34;&gt;Percona XtraBackup 2.4&lt;/a&gt;。&lt;/li&gt;
&lt;li&gt;支持的实例版本：MySQL 5.5、5.6、5.7 高可用版和金融版。&lt;/li&gt;
&lt;li&gt;启用数据加密功能的实例，不支持使用物理备份恢复数据库。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;我使用的是mac，使用brew进行安装 &lt;code&gt;brew install percona-xtrabackup&lt;/code&gt;&lt;/p&gt;
&lt;h3 id=&#34;安装qpress&#34;&gt;安装qpress&lt;/h3&gt;
&lt;p&gt;  从&lt;a href=&#34;http://www.quicklz.com/&#34;&gt;quicklz&lt;/a&gt;下载编译好的二进制文件。 我的mac无法直接使用linux的可执行文件，所以从上面网站下载源码，编译安装。 mac编译qpress时报错&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;qpress.cpp:1040:18: error: use of undeclared identifier &lt;span class=&#34;s1&#34;&gt;&amp;#39;isatty&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nv&#34;&gt;tty_stderr&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; isatty&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;fileno&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;stderr&lt;span class=&#34;o&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                 ^
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; error generated.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;make: *** &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;g++&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; Error &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;qpress.cpp 添加头文件 #include &amp;lt;unistd.h&amp;gt; 重新编译成功。将编译好的qpress拷贝到 /usr/local/bin 。必须放到该目录下，因为xbstream工具调用qpress是用的绝对路径(为啥这样设计￣□￣｜｜)&lt;/p&gt;
&lt;h3 id=&#34;对xb文件进行解包解压缩&#34;&gt;对xb文件进行解包&amp;amp;解压缩&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;xbstream -x -C /tmp/新建的目录 &amp;lt; ~/你的xb文件.xb &lt;span class=&#34;c1&#34;&gt;# 使用 xbstream 命令将备份文件解包到目标目录&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;xtrabackup --decompress --target-dir&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/tmp/新建的目录 &lt;span class=&#34;c1&#34;&gt;# 将目标目录下所有以.qp结尾的文件都解压出来&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;将解压出来的frmibd文件附到本地mysql实例&#34;&gt;将解压出来的frm、ibd文件附到本地mysql实例&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;腾讯云的方法&lt;/strong&gt; 腾讯云文档的方法是起一个mysqld_safe实例将data配置为刚刚那个新建的目录&lt;/p&gt;</description>
    </item>
    <item>
      <title>用php对象，简化Json Schema的定义</title>
      <link>https://blog.foamzou.com/posts/easy-json-schema/</link>
      <pubDate>Sun, 28 Jul 2019 14:30:30 +0800</pubDate>
      <guid>https://blog.foamzou.com/posts/easy-json-schema/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://github.com/foamzou/easy-json-schema&#34;&gt;Github地址&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;使用php对象，描述Json-Schema变得更容易（支持draft-07 和 draft-06）&lt;/li&gt;
&lt;li&gt;使用&lt;a href=&#34;https://github.com/opis/json-schema&#34;&gt;opis/json-schema&lt;/a&gt;作为校验器&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;好处&#34;&gt;&lt;a href=&#34;https://github.com/foamzou/easy-json-schema/blob/master/README.zh-CN.md#%E5%A5%BD%E5%A4%84&#34;&gt;&lt;/a&gt;好处&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;定义容易，不用写复杂的json&lt;/li&gt;
&lt;li&gt;定义更有可读性&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;安装&#34;&gt;&lt;a href=&#34;https://github.com/foamzou/easy-json-schema/blob/master/README.zh-CN.md#%E5%AE%89%E8%A3%85&#34;&gt;&lt;/a&gt;安装&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;composer require &amp;quot;foamzou/easy-json-schema&amp;quot;&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&#34;基本使用&#34;&gt;&lt;a href=&#34;https://github.com/foamzou/easy-json-schema/blob/master/README.zh-CN.md#%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8&#34;&gt;&lt;/a&gt;基本使用&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;use Foamzou\EasyJsonSchema\Manager\Validator;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;use Foamzou\EasyJsonSchema\Manager\Parser;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;use Foamzou\EasyJsonSchema\Type\{
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    Str, Integer
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;// 定义一个schema
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$schema = new Obj([
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;              &amp;#39;name&amp;#39; =&amp;gt; (new Integer)-&amp;gt;min(2)-&amp;gt;max(5),
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;              &amp;#39;age&amp;#39; =&amp;gt; (new Str)-&amp;gt;max(120),
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          ]);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$data = [
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &amp;#39;name&amp;#39; =&amp;gt; &amp;#39;foam&amp;#39;,
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &amp;#39;age&amp;#39; =&amp;gt; 18,
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;// 生成json-schema
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$jsonSchema = Parser::run($schema);
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;//校验数据合法性，如果校验失败，errorMessage将返回具体信息
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$bool = Validator::getInstance()-&amp;gt;isValid($jsonSchema, $data, $errorMessage);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;schema的定义&#34;&gt;&lt;a href=&#34;https://github.com/foamzou/easy-json-schema/blob/master/README.zh-CN.md#schema%E7%9A%84%E5%AE%9A%E4%B9%89&#34;&gt;&lt;/a&gt;Schema的定义&lt;/h2&gt;
&lt;p&gt;下面是与json-schema的对比，可以看到使用php对象的定义会更简单、更有可读性且更容易维护 php版&lt;/p&gt;</description>
    </item>
    <item>
      <title>nginx proxy_pass后gzip不生效</title>
      <link>https://blog.foamzou.com/posts/gzip-not-work-after-proxy_pass/</link>
      <pubDate>Fri, 26 Jul 2019 14:02:23 +0800</pubDate>
      <guid>https://blog.foamzou.com/posts/gzip-not-work-after-proxy_pass/</guid>
      <description>&lt;p&gt;有一台服务器只能对外开80端口，但该服务器有几个项目同时共用。因此做了一个方案，使用不同的url前缀，proxy_pass到对应项目监听的端口。 如default.conf配置如下&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;server &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	listen       &lt;span class=&#34;m&#34;&gt;80&lt;/span&gt; default_server&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	location /a/ &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;           rewrite ^/a/&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;.*&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;$ /&lt;span class=&#34;nv&#34;&gt;$1&lt;/span&gt; break&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;# 剥掉 /a 这一层&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;           proxy_pass http://127.0.0.1:8083&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	location /b/ &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;           rewrite ^/b/&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;.*&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;$ /&lt;span class=&#34;nv&#34;&gt;$1&lt;/span&gt; break&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;           proxy_pass http://127.0.0.1:8084&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	location /c/ &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;           rewrite ^/c/&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;.*&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;$ /&lt;span class=&#34;nv&#34;&gt;$1&lt;/span&gt; break&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;           proxy_pass http://127.0.0.1:8085&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;a项目配置里开启了gzip&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;server &lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    listen 8083&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    root /path/to/a&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    gzip on&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    gzip_comp_level 3&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    ....
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;但发现gzip未生效。 后面把gzip配置放到default.conf的location部分就正常运行了。&lt;/p&gt;</description>
    </item>
    <item>
      <title>编译安装php7.3</title>
      <link>https://blog.foamzou.com/posts/install-php7/</link>
      <pubDate>Thu, 28 Mar 2019 20:59:43 +0800</pubDate>
      <guid>https://blog.foamzou.com/posts/install-php7/</guid>
      <description>&lt;p&gt;最近在一台CentOS6.2的机器上部署php7.3，系统有点旧，稍微折腾点。&lt;/p&gt;
&lt;h2 id=&#34;安装需要的依赖&#34;&gt;安装需要的依赖&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo yum install libxml2 libxml2-devel openssl openssl-devel bzip2 bzip2-devel libjpeg libpng freetype libjpeg-devel libpng-devel freetype-devel gmp-devel readline-devel libxslt-devel libmemcached  libmemcached-devel -y
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;编译安装&#34;&gt;编译安装&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;到&lt;a href=&#34;https://www.php.net/downloads.php&#34;&gt;官网&lt;/a&gt;下载最新的稳定版本&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;注意用户组最好与nginx的保持一致，例如我这里设置与nginx一致的nobody&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;./configure --prefix&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/usr/local/php7 --with-config-file-path&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/usr/local/php7/etc --enable-fpm --with-fpm-user&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;nobody --with-fpm-group&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;nobody --enable-inline-optimization --disable-debug --disable-rpath --enable-shared --enable-soap --with-libxml-dir --with-xmlrpc --with-openssl --with-mhash --with-pcre-regex --with-sqlite3 --with-zlib --enable-bcmath --with-iconv --with-bz2 --enable-calendar --with-curl&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/usr/local/include/curl/ --with-cdb --enable-dom --enable-exif --enable-fileinfo --enable-filter --with-pcre-dir --enable-ftp --with-gd --with-openssl-dir --with-jpeg-dir --with-png-dir --with-zlib-dir --with-freetype-dir --enable-gd-jis-conv --with-gettext --with-gmp --with-mhash --enable-json --enable-mbstring --enable-mbregex --enable-mbregex-backtrack --with-onig --enable-pdo --with-mysqli&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;mysqlnd --with-pdo-mysql&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;mysqlnd --with-zlib-dir --with-pdo-sqlite --with-readline --enable-session --enable-shmop --enable-simplexml --enable-sockets --enable-sysvmsg --enable-sysvsem --enable-sysvshm --enable-wddx --with-libxml-dir --with-xsl --enable-zip --enable-mysqlnd-compression-support --with-pear --enable-opcache
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;make
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo make install
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;编译期间遇到的问题汇总&#34;&gt;编译期间遇到的问题汇总&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;checking for cURL 7.15.5 or greater&amp;hellip; configure: error: cURL version 7.15.5 or later is required to compile php with cURL support&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;实际上我本地已经安装了最新的版本。&amp;ndash;with-curl不指定路径的话，会在/usr/include/curl下找头文件。但我本机已有的libcurl貌似没有这些头文件。尝试`yum install curl curl-devel`，报了一个多版本冲突的问题。所以最后还是从curl官网下载了最新的tar包，手动编译安装后，--with-curl指定路径为/usr/local/include/curl/&lt;/p&gt;</description>
    </item>
    <item>
      <title>用lockf保证同一时间只有一个进程运行</title>
      <link>https://blog.foamzou.com/posts/lockf/</link>
      <pubDate>Mon, 25 Feb 2019 18:20:13 +0800</pubDate>
      <guid>https://blog.foamzou.com/posts/lockf/</guid>
      <description>&lt;h3 id=&#34;安装&#34;&gt;安装&lt;/h3&gt;
&lt;p&gt;参见&lt;a href=&#34;https://github.com/woshizoufeng/lockf&#34;&gt;github&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;使用场景&#34;&gt;使用场景&lt;/h3&gt;
&lt;p&gt;保证同一时间只有一个进程运行。 例如 crontab 设定每分钟跑一次 1.php ，但如果超过1分钟该脚本还没执行完，就会出现多个php脚本同时运行的情况，在某些场景下可能会有问题。 为了满足上述需求，我们可能会在脚本里添加一段代码，创建锁，执行完后删除锁，若锁文件存在则直接return。 还有另一种解决方案就是用 lockf 使用例子：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;lockf -s -t &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; /tmp/xx.lock /usr/local/bin/php -f 1.php
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    <item>
      <title>给你的Mac/Linux的rm装一个回收站</title>
      <link>https://blog.foamzou.com/posts/setup-trash-for-safe-rm/</link>
      <pubDate>Tue, 09 Oct 2018 20:42:41 +0800</pubDate>
      <guid>https://blog.foamzou.com/posts/setup-trash-for-safe-rm/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;作为程序员，在工作中经常用到rm。我在不久前用vscode写代码，在底下的终端里想删掉没用的文件，手抖把未提交到git的代码文件删了。还好代码量不多，否则会崩溃。毕竟重写代码是很痛苦的~ 因此本文标题提上了日程&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;选择一款安全的删除脚本&#34;&gt;选择一款安全的删除脚本&lt;/h3&gt;
&lt;p&gt;Github看到一个脚本满足需求。 &lt;a href=&#34;https://github.com/kaelzhang/shell-safe-rm&#34;&gt;github地址&lt;/a&gt;，里边有多种安装方式。我选择的是npm全局安装。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;npm i -g safe-rm
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;安装后，safe-rm命令就可以用了~&lt;/p&gt;
&lt;h3 id=&#34;将安装好的脚本设置为rm的别名&#34;&gt;将安装好的脚本设置为rm的别名&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;vim编辑~/.bash_profile(或其他bash启动时会执行的文件)。添加 &lt;code&gt;alias rm=&#39;safe-rm&#39;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;由于我使用了fish-shell，因此还需要在fish启动时会执行的config文件里添加别名：vim编辑~/.config/fish/config.fish。添加 &lt;code&gt;alias rm=&#39;safe-rm&#39;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;done&#34;&gt;Done&lt;/h3&gt;
&lt;p&gt;添加完之后别忘了重新打开终端窗口哦（或者source刚刚的配置文件）。至此，rm后文件的被mv到~/.Trash。即使是重名的文件也会在文件尾添加时间后缀，保证文件不被覆盖。&lt;/p&gt;</description>
    </item>
    <item>
      <title>HTTPS原理解析</title>
      <link>https://blog.foamzou.com/posts/about-https/</link>
      <pubDate>Thu, 23 Aug 2018 00:20:25 +0800</pubDate>
      <guid>https://blog.foamzou.com/posts/about-https/</guid>
      <description>&lt;h2 id=&#34;http是什么&#34;&gt;HTTP是什么&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;超文本传输协议（英文：HyperText Transfer Protocol，缩写：HTTP）是互联网上应用最为广泛的一种网络协议。是一个基于请求与响应模式的、无状态的、应用层的协议，常基于TCP的连接方式，绝大多数的Web开发，都是构建在HTTP协议之上的Web应用。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;为了方便通信就必须统一约定好双方的数据协议，如果每个人都搞一套自己的规则，这玩起来就很麻烦了。因此IETF (互联网工程任务组) 推动了HTTP的统一和发展。现在大家用得最多的还是1999年收录于RFC 2616的1.1版本，2015年发布的2.0版本在推广道路上任重道远。&lt;/p&gt;
&lt;h2 id=&#34;https报文&#34;&gt;HTTP[S]报文&lt;/h2&gt;
&lt;p&gt;最直观上的差异，HTTP协议用明文传输报文，HTTPS用密文。  &lt;/p&gt;
&lt;p&gt;&lt;img alt=&#34;报文对比&#34; loading=&#34;lazy&#34; src=&#34;https://blog.foamzou.com/posts/about-https/12842298-abae88306d66e241-2.png&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;http的缺陷&#34;&gt;HTTP的缺陷&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;窃听风险（eavesdropping）：明文传输，第三方可以获知通信内容。&lt;/li&gt;
&lt;li&gt;篡改风险（tampering）：第三方可以修改通信内容。&lt;/li&gt;
&lt;li&gt;冒充风险（pretending）：第三方可以冒充他人身份参与通信。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;https是什么&#34;&gt;HTTPS是什么&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;超文本传输安全协议（英语：Hypertext Transfer Protocol Secure，缩写：HTTPS，常称为HTTP over TLS，HTTP over SSL或HTTP Secure） 是一种透过计算机网络进行安全通信的传输协议。HTTPS经由HTTP进行通信，但利用SSL/TLS协议来加解密数据包。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;HTTPS开发的主要目的，是提供对网站服务器的身份认证，保护交换数据的隐私与完整性； HTTPS并不是一个单独的协议，而是对工作在一加密连接（TLS/SSL）上的常规HTTP协议的称呼。因此HTTPS被称之为身披SSL外壳的HTTP。&lt;/p&gt;
&lt;h2 id=&#34;ssltls协议&#34;&gt;SSL/TLS协议&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;传输层安全性协议（Transport Layer Security，缩写作 TLS），及其前身安全套接层（Secure Sockets Layer，缩写作 SSL）是一种安全协议，目的是为互联网通信，提供安全及数据完整性保障&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;网景公司（Netscape）在1994年推出首版网页浏览器，网景导航者时，推出HTTPS协议，以SSL进行加密，这是SSL的起源。后面，IETF将SSL进行标准化，称为TLS。在浏览器、电子邮件、即时通信、VoIP、网络传真等应用程序中，广泛支持这个协议&lt;/p&gt;
&lt;p&gt;协议&lt;/p&gt;
&lt;p&gt;年份&lt;/p&gt;
&lt;p&gt;描述&lt;/p&gt;
&lt;p&gt;SSL 1.0&lt;/p&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;p&gt;从未公开过，因为存在严重的安全漏洞&lt;/p&gt;
&lt;p&gt;SSL 2.0&lt;/p&gt;
&lt;p&gt;1995&lt;/p&gt;
&lt;p&gt;因为存在数个严重的安全漏洞而被3.0版本替代&lt;/p&gt;
&lt;p&gt;SSL 3.0&lt;/p&gt;
&lt;p&gt;1996&lt;/p&gt;
&lt;p&gt;2014年10月Google发现该版本的严重漏洞，建议全面禁用SSL版本&lt;/p&gt;
&lt;p&gt;TLS 1.0&lt;/p&gt;
&lt;p&gt;1999&lt;/p&gt;
&lt;p&gt;IETF标准化后的第一个版本。包括可以降级到SSL 3.0的实现，这削弱了连接的安全性&lt;/p&gt;
&lt;p&gt;TLS 1.1&lt;/p&gt;
&lt;p&gt;2006&lt;/p&gt;
&lt;p&gt;-&lt;/p&gt;
&lt;p&gt;TLS 1.2&lt;/p&gt;
&lt;p&gt;2008&lt;/p&gt;
&lt;p&gt;删除了对SSL的兼容。目前使用最广泛的版本&lt;/p&gt;
&lt;p&gt;TLS 1.3&lt;/p&gt;
&lt;p&gt;2018&lt;/p&gt;
&lt;p&gt;截至本文撰写，为建议标准的互联网草案&lt;/p&gt;
&lt;h3 id=&#34;在tcpip模型的位置介于传输层与应用层之间&#34;&gt;在TCP/IP模型的位置：介于传输层与应用层之间&lt;/h3&gt;
&lt;p&gt;&lt;img alt=&#34;SSL/TLS在TCP/IP模型的位置&#34; loading=&#34;lazy&#34; src=&#34;https://blog.foamzou.com/posts/about-https/12842298-cfed569a5b9bd924-2.png&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>排查elasticsearch的cpu居高不下，查询慢的问题</title>
      <link>https://blog.foamzou.com/posts/cpu-of-elasticsearch-high-search-slow/</link>
      <pubDate>Mon, 16 Jul 2018 13:16:26 +0800</pubDate>
      <guid>https://blog.foamzou.com/posts/cpu-of-elasticsearch-high-search-slow/</guid>
      <description>&lt;h2 id=&#34;背景&#34;&gt;背景&lt;/h2&gt;
&lt;p&gt;近来es查询很慢，kibana的discover界面偶尔还会因为查询请求超时而无法显示数据。&lt;code&gt;/_cat/indices?v&lt;/code&gt; 等对es的查询也慢的出奇，需要1、2分钟才返回结果。&lt;/p&gt;
&lt;h2 id=&#34;排查&#34;&gt;排查&lt;/h2&gt;
&lt;p&gt;top命令看了es的java进程，发现cpu一直很高，130%左右，一直没有下降过。查看es的日志，发现gc.log中几乎每秒都要触发一次GC &lt;code&gt;Full GC (Allocation Failure)&lt;/code&gt;。内存不够用，又没有内存可回收，所以GC也不断。怪不得CPU这么高，大部分时间都用在gc上面了。&lt;/p&gt;
&lt;h2 id=&#34;处理&#34;&gt;处理&lt;/h2&gt;
&lt;p&gt;调整es可使用的内存大小。编辑&lt;code&gt;config/jvm.options&lt;/code&gt;，调整了Xms和Xmx的大小，由原来默认的1g调整为10g。（官方建议这个值不要超过物理内存的50%，也不要超过32G。详见&lt;a href=&#34;https://www.elastic.co/guide/en/elasticsearch/reference/current/heap-size.html&#34;&gt;官网说明&lt;/a&gt;）接着重启es就好了。观察cpu，虽然偶尔也会彪上130%，但总体来说正常了，查询也变得很快。 ps：es重启后，需要观察logstash是否退出了。如果退出，需要重新把logstash拉起来。 pss：这次是小坑，后面可能还有很多大坑需要踩。后续有cpu高、查询慢的问题也一并归类到该文。&lt;/p&gt;</description>
    </item>
    <item>
      <title>mysql命令行神器mycli</title>
      <link>https://blog.foamzou.com/posts/mycli/</link>
      <pubDate>Sun, 22 Apr 2018 00:24:14 +0800</pubDate>
      <guid>https://blog.foamzou.com/posts/mycli/</guid>
      <description>&lt;h2 id=&#34;为什么使用它&#34;&gt;为什么使用它&lt;/h2&gt;
&lt;p&gt;受够了mysql原生client后，你会爱上mycli的自动补全和高亮。对于我这种常常记不住表结构的人来说，自动补全真是爽得不行。 ps：sql新手谨慎使用，建议多裸写sql后再来使用该软件&lt;/p&gt;
&lt;h2 id=&#34;安装&#34;&gt;安装&lt;/h2&gt;
&lt;p&gt;Mac&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;brew install mycli
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;CentOS&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 请尽量先将pip升级到最新版本&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pip install --upgrade pip
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;yum install python-devel
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;yum install libffi-devel 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;easy_install mycli
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;使用方法&#34;&gt;使用方法&lt;/h2&gt;
&lt;p&gt;和mysql原生命令行一样：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;mycli -uname
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    <item>
      <title>NodeJs中将TinyInt转换为Boolean</title>
      <link>https://blog.foamzou.com/posts/convert-tinyint-to-boolean-in-nodejs/</link>
      <pubDate>Sun, 14 Jan 2018 22:59:41 +0800</pubDate>
      <guid>https://blog.foamzou.com/posts/convert-tinyint-to-boolean-in-nodejs/</guid>
      <description>&lt;p&gt;Mysql的基本数据类型中并没有布尔型，之所以建表和数据操作中能够使用BOOLEAN是因为mysql将其作为了tinyint(1)的别名。用0表示false，1表示true。 但开发过程中，既然我们给某一字段定义为布尔型，那么在我们获取数据后，期望得到的必然是布尔值而不是0或1。因此我们可以在得到返回值后转换一下。 这里我使用的是mysql模块，该模块允许给typeCase属性设置一个回调函数。详见&lt;a href=&#34;https://github.com/mysqljs/mysql#string&#34;&gt;官网说明&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;connection&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;query&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;sql&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;...&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;typeCast&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;field&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;next&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;field&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;TINY&amp;#39;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;field&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;length&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;field&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;1&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 1 = true, 0 = false
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;next&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;但这也意味着使用该方法的项目不能使用tinyInt(1)类型了，自行取舍吧~&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
