1 Star 0 Fork 0

webwlsong / webwlsong

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
atom.xml 158.38 KB
一键复制 编辑 原始数据 按行查看 历史
Travis CI User 提交于 2020-09-23 16:36 . Gitee Pages Build
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>webwlsong</title>
<subtitle></subtitle>
<link href="/atom.xml" rel="self"/>
<link href="https://webwlsong.gitee.io/"/>
<updated>2020-09-23T16:35:34.793Z</updated>
<id>https://webwlsong.gitee.io/</id>
<author>
<name>webwlsong</name>
</author>
<generator uri="http://hexo.io/">Hexo</generator>
<entry>
<title>图解微信第三方开放平台流程图</title>
<link href="https://webwlsong.gitee.io/2020/09/23/2020/2020-09/2020-09-24/"/>
<id>https://webwlsong.gitee.io/2020/09/23/2020/2020-09/2020-09-24/</id>
<published>2020-09-23T16:00:00.000Z</published>
<updated>2020-09-23T16:35:34.793Z</updated>
<content type="html"><![CDATA[<h2 id="微信第三方开放平台流程图"><a class="markdownIt-Anchor" href="#微信第三方开放平台流程图"></a> 微信第三方开放平台流程图</h2><p><img src="https://i.loli.net/2020/09/24/Ost8Vo36UifjFIB.png" alt="微信第三方开放平台流程图"></p><h2 id="授权流程技术说明"><a class="markdownIt-Anchor" href="#授权流程技术说明"></a> 授权流程技术说明</h2><p>小程序或者公众号授权给第三方平台的技术实现流程比较简单,如下图所示:<br>第三方服务商构建授权链接放置自己的网站,用户点击后,弹出授权页面<br><img src="https://i.loli.net/2020/09/24/T58OrHo1KNWqGfX.jpg" alt="0"><br>账号管理员扫码,选择需要授权的账号,进行授权。<br><img src="https://i.loli.net/2020/09/24/S4Qcg5xRPEhq6rJ.jpg" alt="0 -1-"><br>用户可自定义选择权限集进行授权<br><img src="https://i.loli.net/2020/09/24/EXnS63idLP8ekJt.png" alt="g-sXXzWmk61svoMroJyjjEcJY8qb0JFTNsh22E44EbHUD3ciJfmtXBtPZ73hezHt"></p><p>下面对其进行详细介绍:</p><ul><li><p>步骤 1:第三方平台方获取预授权码(pre_auth_code)<br><a href="https://developers.weixin.qq.com/doc/oplatform/Third-party_Platforms/api/pre_auth_code.html" target="_blank" rel="noopener">详见</a></p></li><li><p>步骤 2:引入用户进入授权页</p></li></ul><p>第三方平台方可以在自己的网站中放置“微信公众号授权”或者“小程序授权”的入口,或生成授权链接放置在移动网页中,引导公众号和小程序管理员进入授权页。</p><p>方式一:授权注册页面扫码授权</p><p>授权页网址为:<br><a href="https://mp.weixin.qq.com/cgi-bin/componentloginpage?component_appid=xxxx&amp;pre_auth_code=xxxxx&amp;redirect_uri=xxxx&amp;auth_type=xxx%E3%80%82" target="_blank" rel="noopener">https://mp.weixin.qq.com/cgi-bin/componentloginpage?component_appid=xxxx&amp;pre_auth_code=xxxxx&amp;redirect_uri=xxxx&amp;auth_type=xxx。</a></p><p><em>参考文献:</em></p><ul><li><em>微信第三方平台授权流程技术说明<br><a href="https://developers.weixin.qq.com/doc/oplatform/Third-party_Platforms/Third_party_platform_appid.html" target="_blank" rel="noopener">https://developers.weixin.qq.com/doc/oplatform/Third-party_Platforms/Third_party_platform_appid.html</a></em></li></ul>]]></content>
<summary type="html">
&lt;h2 id=&quot;微信第三方开放平台流程图&quot;&gt;&lt;a class=&quot;markdownIt-Anchor&quot; href=&quot;#微信第三方开放平台流程图&quot;&gt;&lt;/a&gt; 微信第三方开放平台流程图&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://i.loli.net/2020/09/24/Os
</summary>
<category term="小程序" scheme="https://webwlsong.gitee.io/categories/%E5%B0%8F%E7%A8%8B%E5%BA%8F/"/>
<category term="小程序" scheme="https://webwlsong.gitee.io/tags/%E5%B0%8F%E7%A8%8B%E5%BA%8F/"/>
</entry>
<entry>
<title>pyenv的安装和简单使用(git、pyenv、pyenv-virtualenv)</title>
<link href="https://webwlsong.gitee.io/2020/09/17/2020/2020-09/2020-09-18/"/>
<id>https://webwlsong.gitee.io/2020/09/17/2020/2020-09/2020-09-18/</id>
<published>2020-09-17T16:00:00.000Z</published>
<updated>2020-09-23T16:35:34.793Z</updated>
<content type="html"><![CDATA[<p>[TOC]</p><p><img src="https://i.loli.net/2020/09/18/7eGfMl86NDjUkFd.jpg" alt="python生态工具"></p><h1 id="python工作环境管理"><a class="markdownIt-Anchor" href="#python工作环境管理"></a> Python工作环境管理</h1><p>Python 2和Python 3之间存在着较大的差异,并且,由于各种原因导致了Python 2和Python 3的长期 共存。在实际工作过程中,我们可能会同时用到Python 2和Python 3,因此,需要经常在Python 2和 Python 3之间进行来回切换。此外,如果你是喜欢尝鲜的人,那么,你很有可能在Python新版本出来 的时候立即下载Python的版本,试验Python的特性。</p><p>在Python世界里,除了需要对Python的版本进行管理以外,还需要对不同的软件包进行管理。大部分 情况下,对于开源的库我们使用版本即可。但是,有时候可能需要对相同的Python版本,在不同的 项目中使用不同版本的软件包。</p><p>在这一节里,我们将介绍两个工具,即pyenv和virtualenv。前者用于管理不同的Python版本,后者用 于管理不同的工作环境。有了这两个工具,Python相关的版本问题将不再是问题。</p><h2 id="1-情景问题"><a class="markdownIt-Anchor" href="#1-情景问题"></a> 1、情景问题</h2><ol><li>Python解释器版本混乱, 2和3差别巨大, 而且细分版本也不尽相同, 难以选择和管理.</li><li>不同Linux发行版自带Python不同, 如ubuntu16自带2.7和3.5版本, 其中系统许多组件依赖于自带解释器, 一旦删除或者更改都可能会造成系统出问题.</li><li>不同的Python解释器软件包管理也是问题, 如pip和ipython等必备包组件, 而且在项目开发中如何保证不同的包环境互不干扰也是一个问题.</li><li></li></ol><p>那么有没有一个终极的解决办法能在管理不同解释器版本的同时控制不同的包环境呢? 有的, 就是pyenv.</p><h2 id="2-使用pyenv管理不同的python版本"><a class="markdownIt-Anchor" href="#2-使用pyenv管理不同的python版本"></a> 2、使用pyenv管理不同的Python版本</h2><p>安装不同的Python版本并不是一件容易的事情,在不同的Python版本之间来回切换更加困难,而且, 多版本并存非常容易互相干扰。因此,我们需要一个名为pyenv的工具。pyenv是一个Python版本管理 工具,它能够进行全局的Python版本切换,也可以为单个项目提供对应的Python版本。使用pyenv以 后,可以在服务器上安装多个不同的Python版本,也可以安装不同的Python实现。不同Python版本之 间的切换也非常简单。接下来我们就一起看一下pyenv的安装和使用。</p><h2 id="pyenv是什么-能干什么"><a class="markdownIt-Anchor" href="#pyenv是什么-能干什么"></a> pyenv是什么? 能干什么?</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">pyenv是一个forked自ruby社区的简单、低调、遵循UNIX哲</span><br><span class="line"></span><br><span class="line">学的Python环境管理工具, 它可以轻松切换全局解释器版本, </span><br><span class="line"></span><br><span class="line">同时结合vitualenv插件可以方便的管理对应的包源.</span><br></pre></td></tr></table></figure><p>我们知道, 在terminal中输入一个命令比如‘ls’时, shell会从当前环境的PATH中的各个目录里看是不是有ls这个可执行文件, 如果找到就执行, 否则就会报‘command no found’ 的错误, 同理, 只要控制PATH变量就能够做到python版本的切换, pyenv通过在PATH头部插入shims路径来实现对python版本的控制.</p><p>pyenv和流行的pipenv、virtualenv的关系</p><p>pipenv是requests 作者 Kenneth Reitz大神写的一个python虚拟环境管理工具, 结合了pip和virtualenv的功能, 侧重点还是在包环境管理上, 使用思路是先创建一个指定python版本的环境, 然后在此环境上安装相应的包, 好评不错, 看到很多大牛都在推荐.</p><p>pipenv是requests 作者 Kenneth Reitz大神写的一个python虚拟环境管理工具, 结合了pip和virtualenv的功能, 侧重点还是在包环境管理上, 使用思路是先创建一个指定python版本的环境, 然后在此环境上安装相应的包, 好评不错, 看到很多大牛都在推荐.</p><p>pyenv相对来说知名度就差很多了, 不过也很稳定, 这三个环境管理工具我都用过, 我个人更喜欢pyenv, 理由如下:</p><ol><li>相对于其他两个工具, pyenv更侧重在python 解释器版本管理上, 比包管理更大一个层级, 使用pyenv我可以方便的下载指定版本的python解释器, pypy, anaconda等, 可以随时自由的在shell环境中本地、全局切换python解释器</li><li>开发的时候不需要限定某个版本的虚拟环境, 只需要在部署的时候用pyenv指定某个版本就好了</li><li>pyenv切换解释器版本的时候, pip和ipython以及对应的包环境都是一起切换的, 所以如果你要同时运行ipython2.x和ipython3.x多个解释器验证一些代码时就很方便</li><li>pyenv也可以创建好指定的虚拟环境, 但不需要指定具体目录, 自由度更高, 使用也简单</li></ol><h2 id="4-简单使用"><a class="markdownIt-Anchor" href="#4-简单使用"></a> 4、简单使用</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 查看当前版本</span></span><br><span class="line">pyenv version</span><br><span class="line"></span><br><span class="line"><span class="comment"># 查看所有版本</span></span><br><span class="line">pyenv versions</span><br><span class="line"></span><br><span class="line"><span class="comment"># 查看所有可安装的版本</span></span><br><span class="line">pyenv install --list</span><br><span class="line"></span><br><span class="line"><span class="comment"># 安装指定版本</span></span><br><span class="line">pyenv install 3.6.5</span><br><span class="line"><span class="comment"># 安装新版本后rehash一下</span></span><br><span class="line">pyenv <span class="built_in">rehash</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 删除指定版本</span></span><br><span class="line">pyenv uninstall 3.5.2</span><br><span class="line"></span><br><span class="line"><span class="comment"># 指定全局版本</span></span><br><span class="line">pyenv global 3.6.5</span><br><span class="line"></span><br><span class="line"><span class="comment"># 指定多个全局版本, 3版本优先</span></span><br><span class="line">pyenv global 3.6.5 2.7.14</span><br><span class="line"></span><br><span class="line"><span class="comment"># 实际上当你切换版本后, 相应的pip和包仓库都是会自动切换过去的</span></span><br></pre></td></tr></table></figure><h2 id="一-pyenv安装"><a class="markdownIt-Anchor" href="#一-pyenv安装"></a> 一、pyenv安装</h2><ol><li>安装 pyenv</li></ol><p>说明:本文的所有安装都严格遵守官方文档,与官方文档完全保持一致。</p><p>git 地址:<a href="https://github.com/pyenv/pyenv" target="_blank" rel="noopener">https://github.com/pyenv/pyenv</a></p><p>在你的终端中执行如下命令,安全无毒,请放心食用:</p><p>首先把项目克隆下来,放在家目录下的隐藏文件夹中:.pyenv</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git clone https://github.com/pyenv/pyenv.git ~/.pyenv</span><br></pre></td></tr></table></figure><p>然后配置变量</p><p>如果你使用 bash,就依次执行如下命令:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">echo</span> <span class="string">'export PYENV_ROOT="$HOME/.pyenv"'</span> &gt;&gt; ~/.bashrc</span><br><span class="line"><span class="built_in">echo</span> <span class="string">'export PATH="$PYENV_ROOT/bin:$PATH"'</span> &gt;&gt; ~/.bashrc</span><br><span class="line"><span class="built_in">echo</span> -e <span class="string">'if command -v pyenv 1&gt;/dev/null 2&gt;&amp;1; then\n eval "$(pyenv init -)"\nfi'</span> &gt;&gt; ~/.bashrc</span><br></pre></td></tr></table></figure><p>如果你使用 zsh,就依次执行如下命令:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">echo</span> <span class="string">'export PYENV_ROOT="$HOME/.pyenv"'</span> &gt;&gt; ~/.zshrc</span><br><span class="line"><span class="built_in">echo</span> <span class="string">'export PATH="$PYENV_ROOT/bin:$PATH"'</span> &gt;&gt; ~/.zshrc</span><br><span class="line"><span class="built_in">echo</span> -e <span class="string">'if command -v pyenv 1&gt;/dev/null 2&gt;&amp;1; then\n eval "$(pyenv init -)"\nfi'</span> &gt;&gt; ~/.zshrc</span><br></pre></td></tr></table></figure><p>echo 命令的含义是:将引号中内容写入某文件中<br>请注意,以上的三条 echo 命令的最后一条长长的命令,请你保证它引号中的内容处于 ~/.bashrc 或者 ~/.zshrc 的最底部。<br>因为在 pyenv 初始化期间会操作 path 环境变量,导致不可预测的行为。<br>查看文件的底部内容,可以使用 tail 命令,用法:tail ~/.bashrc 或者 tail ~/.zshrc,编辑文件可以使用 vim 或者 vscode</p><p>最后,在使用 pyenv 之前,重新初始化 shell 环境,执行如下命令</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">exec</span> <span class="variable">$SHELL</span> 或者 <span class="built_in">source</span></span><br></pre></td></tr></table></figure><p>不执行该命令也是完全可以的,你可以关闭当前的终端窗口,重新启动一个就可以了。</p><p>此时,你已经完成了 pyenv 的安装了,你使用可以它的全部命令了,但是我建议你先别急着用,一口气装完 pyenv 的一个插件,那就是 pyenv-virtualenv</p><ol start="2"><li>安装 pyenv-virtualenv</li></ol><p>virtualenv本身是一个独立的项目,用以隔离不同项目的工作环境。例如,用户lmx希望在项目A中使用 Flask 0.8这个版本,与此同时,又想在项目B中使用Flask 0.9这个版本。如果我们全局安装Flask,必然 无法满足用户的需求。这个时候,我们就可以使用virtualenv。</p><p>读者需要注意pyenv和virtualenv的区别。pyenv用以管理不同的Python版本,例如,你的系统工作时 使用Python 2.7.13,学习时使用Python 3.6.0。virtualenv用以隔离项目的工作环境,例如,项目A和 项目B都是使用Python 2.7.13,但是,项目A需要使用Flask 0.8版本,项目B需要使用Flask 0.9版本。我 们只要组合pyenv和virtualenv这两个工具,就能够构造Python和第三方库的任意版本组合,拥有很好 的灵活性,也避免了项目之间的相互干扰。</p><p>virtualenv本身是一个独立的工具,用户可以不使用pyenv而单独使用virtualenv。但是,如果你使用了 pyenv,就需要安装pyenv-virtualenv插件,而不是通过virtualenv软件使用virtualenv的功能。</p><p>git 地址:<a href="https://github.com/pyenv/pyenv-virtualenv" target="_blank" rel="noopener">https://github.com/pyenv/pyenv-virtualenv</a></p><p>(1) 把插件克隆在刚才已经安装完毕的 pyenv 的 plugins 文件夹中</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git <span class="built_in">clone</span> https://github.com/pyenv/pyenv-virtualenv.git $(pyenv root)/plugins/pyenv-virtualenv</span><br></pre></td></tr></table></figure><p>(2) 然后配置环境变量<br>如果你使用 bash,就执行如下命令:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">echo</span> <span class="string">'eval "$(pyenv virtualenv-init -)"'</span> &gt;&gt; ~/.bashrc</span><br></pre></td></tr></table></figure><p>如果你使用 zsh,就执行如下命令:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">echo</span> <span class="string">'eval "$(pyenv virtualenv-init -)"'</span> &gt;&gt; ~/.zshrc</span><br></pre></td></tr></table></figure><p>(3) 最后,在使用 pyenv 之前,重新初始化 shell 环境,执行如下命令</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">exec</span> <span class="variable">$SHELL</span></span><br></pre></td></tr></table></figure><p>不执行该命令也是完全可以的,你可以关闭当前的终端窗口,重新启动一个就可以了。</p><p>至此,pyenv就安装完成了,我们可以通过下面的命令验证pyenv是否正确安装并获取pyenv的帮助信息:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line">pyenv --<span class="built_in">help</span></span><br><span class="line">Usage: pyenv &lt;<span class="built_in">command</span>&gt; [&lt;args&gt;]</span><br><span class="line"></span><br><span class="line">Some useful pyenv commands are:</span><br><span class="line"> --version Display the version of pyenv</span><br><span class="line"> activate Activate virtual environment</span><br><span class="line"> commands List all available pyenv commands</span><br><span class="line"> deactivate Deactivate virtual environment</span><br><span class="line"> <span class="built_in">exec</span> Run an executable with the selected Python version</span><br><span class="line"> global Set or show the global Python version(s)</span><br><span class="line"> <span class="built_in">help</span> Display <span class="built_in">help</span> <span class="keyword">for</span> a <span class="built_in">command</span></span><br><span class="line"> hooks List hook scripts <span class="keyword">for</span> a given pyenv <span class="built_in">command</span></span><br><span class="line"> init Configure the shell environment <span class="keyword">for</span> pyenv</span><br><span class="line"> install Install a Python version using python-build</span><br><span class="line"> <span class="built_in">local</span> Set or show the <span class="built_in">local</span> application-specific Python version(s)</span><br><span class="line"> prefix Display prefix <span class="keyword">for</span> a Python version</span><br><span class="line"> <span class="built_in">rehash</span> Rehash pyenv shims (run this after installing executables)</span><br><span class="line"> root Display the root directory <span class="built_in">where</span> versions and shims are kept</span><br><span class="line"> shell Set or show the shell-specific Python version</span><br><span class="line"> shims List existing pyenv shims</span><br><span class="line"> uninstall Uninstall a specific Python version</span><br><span class="line"> version Show the current Python version(s) and its origin</span><br><span class="line"> version-file Detect the file that sets the current pyenv version</span><br><span class="line"> version-name Show the current Python version</span><br><span class="line"> version-origin Explain how the current Python version is <span class="built_in">set</span></span><br><span class="line"> versions List all Python versions available to pyenv</span><br><span class="line"> virtualenv Create a Python virtualenv using the pyenv-virtualenv plugin</span><br><span class="line"> virtualenv-delete Uninstall a specific Python virtualenv</span><br><span class="line"> virtualenv-init Configure the shell environment <span class="keyword">for</span> pyenv-virtualenv</span><br><span class="line"> virtualenv-prefix Display real_prefix <span class="keyword">for</span> a Python virtualenv version</span><br><span class="line"> virtualenvs List all Python virtualenvs found <span class="keyword">in</span> `<span class="variable">$PYENV_ROOT</span>/versions/*<span class="string">'.</span></span><br><span class="line"><span class="string"> whence List all Python versions that contain the given executable</span></span><br><span class="line"><span class="string"> which Display the full path to an executable</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">See `pyenv help &lt;command&gt;'</span> <span class="keyword">for</span> information on a specific <span class="built_in">command</span>.</span><br><span class="line">For full documentation, see: https://github.com/pyenv/pyenv<span class="comment">#readme</span></span><br></pre></td></tr></table></figure><h2 id="二-使用-pyenv"><a class="markdownIt-Anchor" href="#二-使用-pyenv"></a> 二、使用 pyenv</h2><p>此处仅仅展示 pyenv 和 virtualenv 的日常用法</p><p>1、检查安装是否正确<br>检查 pyenv 的版本</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">[root@python ~]<span class="comment"># pyenv version</span></span><br><span class="line">(<span class="built_in">set</span> by /root/.pyenv/version)</span><br><span class="line">查看 pyenv 已经管理了哪些 python 版本</span><br><span class="line">[root@python ~]<span class="comment">#pyenv versions</span></span><br><span class="line">* system (<span class="built_in">set</span> by /root/.pyenv/version)</span><br></pre></td></tr></table></figure><p>如果你看到了正常的版本信息,就说明可以了,如果看到了类似于 command not found 之类的,就说明安装失败了。</p><p>我们通过pyenv的install命令,可以查看pyenv当前支持哪些Python版本,如下所示:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">[root@python ~]<span class="comment"># pyenv install --list </span></span><br><span class="line">Available versions:</span><br><span class="line">2.1.3</span><br><span class="line">……省略部分信息</span><br><span class="line">3.8.0</span><br><span class="line">3.8-dev</span><br><span class="line">3.8.1</span><br><span class="line">3.9-dev</span><br><span class="line">……省略部分信息</span><br><span class="line">anaconda3-2018.12</span><br><span class="line">anaconda3-2019.03</span><br><span class="line">anaconda3-2019.07</span><br><span class="line">anaconda3-2019.10</span><br><span class="line">……省略部分信息</span><br><span class="line">[root@python ~]<span class="comment">#</span></span><br></pre></td></tr></table></figure><p>2、pyenv切换python版本<br>由于pyenv可以安装的Python版本列表非常长,所以,这里进行了省略。读者可以在自己电脑上安装 pyenv,然后执行pyenv install --list命令进行查看。可以看到,pyenv不但可以安装不同的Python版 本,而且还可以安装不同的Python实现,也可以安装版本的Python用以学习。</p><p>查看当前系统中包含的Python版本:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">[root@python ~]<span class="comment"># pyenv versions </span></span><br><span class="line">* system (<span class="built_in">set</span> by /root/.pyenv/version)</span><br><span class="line">使用pyenv安装不同的Python版本:</span><br><span class="line">[root@python ~]<span class="comment">#pyenv install -v 3.8.1 </span></span><br><span class="line">[root@python ~]<span class="comment">#pyenv install -v 2.7.13</span></span><br></pre></td></tr></table></figure><p>再次查看当前系统中包含的Python版本</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">[root@python ~]<span class="comment"># pyenv versions</span></span><br><span class="line">* system (<span class="built_in">set</span> by /root/.pyenv/version)</span><br><span class="line"> 2.7.13</span><br><span class="line"> 3.8.1</span><br></pre></td></tr></table></figure><ol start="3"><li>切换前为3.8.1</li></ol><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#切换当前为3.8.1</span></span><br><span class="line">[root@python ~]<span class="comment"># python</span></span><br><span class="line">Python 3.8.1 (default, Apr 20 2020, 15:00:10) </span><br><span class="line">[GCC 4.8.5 20150623 (Red Hat 4.8.5-39)] on linux</span><br><span class="line">Type <span class="string">"help"</span>, <span class="string">"copyright"</span>, <span class="string">"credits"</span> or <span class="string">"license"</span> <span class="keyword">for</span> more informatio</span><br></pre></td></tr></table></figure><ol start="4"><li>切换为2.7.13</li></ol><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">[root@python ~]<span class="comment"># pyenv global 2.7.13 </span></span><br><span class="line">[root@python ~]<span class="comment"># python</span></span><br><span class="line">Python 2.7.13 (default, Apr 20 2020, 15:04:15) </span><br><span class="line">[GCC 4.8.5 20150623 (Red Hat 4.8.5-39)] on linux2</span><br><span class="line">Type <span class="string">"help"</span>, <span class="string">"copyright"</span>, <span class="string">"credits"</span> or <span class="string">"license"</span> <span class="keyword">for</span> more information.</span><br></pre></td></tr></table></figure><p>使用pyenv以后,可以快速切换Python的版本。切换Python版本以后,与版本相关的依赖也会一起切 换。因此,我们不用担心不同的版本在系统中是否会相互干扰。例如,切换Python版本以后,相应的 pip也会跟着切换,所以不用担心自己使用的pip版本和Python版本不匹配的问题,如下所示:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">[root@python ~]<span class="comment"># pyenv global 3.8.1</span></span><br><span class="line">[root@python ~]<span class="comment"># pip --version</span></span><br><span class="line">pip 19.2.3 from /root/.pyenv/versions/3.8.1/lib/python3.8/site-packages/pip (python 3.8)</span><br><span class="line">如果想要删除Python版本,使用uninstall命令即可。如下所示:</span><br><span class="line">[root@python ~]<span class="comment"># pyenv uninstall 2.7.10</span></span><br></pre></td></tr></table></figure><h2 id="三-pyenv-virtualenv的使用"><a class="markdownIt-Anchor" href="#三-pyenv-virtualenv的使用"></a> 三、pyenv-virtualenv的使用</h2><p>有了pyenv-virtualenv以后,我们可以为同一个Python解释器,创建多个不同的工作环境。例如,我们 新建两个工作环境:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">[root@python ~]<span class="comment"># pyenv virtualenv 3.8.1 first_project </span></span><br><span class="line">[root@python ~]<span class="comment"># pyenv virtualenv 3.8.1 second_projec</span></span><br><span class="line">可以使用virtualenvs子命令查看工作环境</span><br><span class="line">[root@python ~]<span class="comment"># pyenv virtualenvs</span></span><br><span class="line"> 3.8.1/envs/first_project (created from /root/.pyenv/versions/3.8.1)</span><br><span class="line"> 3.8.1/envs/second_projec (created from /root/.pyenv/versions/3.8.1)</span><br><span class="line"> first_project (created from /root/.pyenv/versions/3.8.1)</span><br><span class="line"> second_projec (created from /root/.pyenv/versions/3.8.1)</span><br></pre></td></tr></table></figure><p>创建完工作环境以后,可以通过activate和deactivate子命令进入或退出一个工作环境。进入工作环境 以后,左边的提示符会显示你当前所在的工作环境,以免因为环境太多导致操作错误。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">(first_project) </span><br><span class="line">[root@python ~]<span class="comment"># pip install flask==1.1.1 </span></span><br><span class="line">Looking <span class="keyword">in</span> indexes: https://pypi.doubanio.com/simple</span><br><span class="line">Collecting flask==1.1.1</span><br><span class="line"> Downloading https://pypi.doubanio.com/packages/9b/93/628509b8d5dc749656a9641f4caf13540e2cdec85276964ff8f43bbb1d3b/Flask-1.1.1-py2.py3-none-any.whl (94kB)</span><br><span class="line"> |███▌ | 10kB 28.0MB/s eta 0:00:</span><br><span class="line"> |███████ | 20kB 1.8MB/s eta 0:00:0</span><br><span class="line"> |██████████▍ | 30kB 2.7MB/s eta 0:00:0</span><br><span class="line"> |█████████████▉ | 40kB 1.8MB/s eta 0:00:0</span><br><span class="line"> |█████████████████▍ | 51kB 1.3MB/s eta 0:00:0</span><br><span class="line"> |████████████████████▉ | 61kB 1.5MB/s eta 0:00:0</span><br><span class="line"> |████████████████████████▎ | 71kB 1.4MB/s eta 0:00:0</span><br><span class="line"> |███████████████████████████▊ | 81kB 1.3MB/s eta 0:00:0</span><br><span class="line"> |███████████████████████████████▏| 92kB 1.4MB/s eta 0:00:0</span><br><span class="line"> |████████████████████████████████| 102kB 1.6MB/s </span><br><span class="line">Collecting itsdangerous&gt;=0.24 (from flask==1.1.1)</span><br><span class="line">(first_project) [root@python ~]<span class="comment"># pyenv deactivate</span></span><br><span class="line"><span class="comment">## 退出first_project环境</span></span><br><span class="line">[root@python ~]<span class="comment">#</span></span><br></pre></td></tr></table></figure><p>接下来,我们看一下在不同的工作环境安装不同的Flask版本</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">[root@python ~]<span class="comment"># pyenv activate first_project </span></span><br><span class="line"><span class="comment">##切换工作环境</span></span><br><span class="line">(first_project) [root@python ~]<span class="comment"># pip install flask==1.1.1 </span></span><br><span class="line"><span class="comment">##安装1.1.1的flask</span></span><br><span class="line">(first_project) [root@python ~]<span class="comment"># pyenv deactivate </span></span><br><span class="line"><span class="comment">##退出目前工作环境</span></span><br><span class="line">[root@python ~]<span class="comment">#</span></span><br><span class="line"></span><br><span class="line">[root@python ~]<span class="comment"># pyenv activate second_projec</span></span><br><span class="line"><span class="comment">##切换工作环境</span></span><br><span class="line">(second_project) [root@python ~]<span class="comment"># pip install flask==0.10.1</span></span><br><span class="line"><span class="comment">##安装0.10.1的flask</span></span><br><span class="line">(second_project) [root@python ~]<span class="comment"># pyenv deactivate </span></span><br><span class="line"><span class="comment">##退出目前工作环境</span></span><br><span class="line">[root@python ~]<span class="comment">#</span></span><br></pre></td></tr></table></figure><p>查看一下两个工作环境源目录<br>pyenv的安装和简单使用(git、pyenv、pyenv-virtualenv)</p><p>如果想要删除虚拟环境,则使用:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">(first_project)</span><br><span class="line"> [root@python ~]<span class="comment"># pyenv virtualenv-delete first_project</span></span><br></pre></td></tr></table></figure><p>使用pyenv和python-virtualenv插件,我们就能够自由地在不同的版本之间进行切换,相比管理Python 版本,不但节省了时间,也避免了工作过程中的相互干扰。</p><h2 id="四-更新-pyenv"><a class="markdownIt-Anchor" href="#四-更新-pyenv"></a> 四、更新 pyenv</h2><p>由于我们是 git 克隆的,所以更新非常简单</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cd</span> ~/.pyenv` 或者 `<span class="built_in">cd</span> $(pyenv root)`</span><br><span class="line"> `git pull</span><br></pre></td></tr></table></figure><h2 id="五-卸载-pyenv"><a class="markdownIt-Anchor" href="#五-卸载-pyenv"></a> 五、卸载 pyenv</h2><p>由于 pyenv 把一切都放在 ~/.pyenv 下了,所以卸载很方便,两个步骤就行了</p><p>首先你需要删除环境变量</p><p>然后你需要执行:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">rm -rf ~/.pyenv` 或者 `rm -rf $(pyenv root)</span><br></pre></td></tr></table></figure><p><em>载录文献:</em></p><ul><li><em>pyenv的安装和简单使用(git、pyenv、pyenv-virtualenv)<br><a href="https://blog.51cto.com/14320361/2488888" target="_blank" rel="noopener">https://blog.51cto.com/14320361/2488888</a></em></li></ul>]]></content>
<summary type="html">
&lt;p&gt;[TOC]&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://i.loli.net/2020/09/18/7eGfMl86NDjUkFd.jpg&quot; alt=&quot;python生态工具&quot;&gt;&lt;/p&gt;
&lt;h1 id=&quot;python工作环境管理&quot;&gt;&lt;a class=&quot;markdownI
</summary>
<category term="python" scheme="https://webwlsong.gitee.io/categories/python/"/>
<category term="python" scheme="https://webwlsong.gitee.io/tags/python/"/>
<category term="pyenv" scheme="https://webwlsong.gitee.io/tags/pyenv/"/>
</entry>
<entry>
<title>图解Golang的内存管理分配</title>
<link href="https://webwlsong.gitee.io/2020/09/02/2020/2020-09/2020-09-02/"/>
<id>https://webwlsong.gitee.io/2020/09/02/2020/2020-09/2020-09-02/</id>
<published>2020-09-02T16:00:00.000Z</published>
<updated>2020-09-23T16:35:34.793Z</updated>
<content type="html"><![CDATA[<p>go主要有以下五种内存存储区(c/c++也是一样):</p><p><img src="https://webwlsong-1301722012.cos.ap-shanghai.myqcloud.com/mweb/2020/09/03/1599064164048.jpg" alt="内存分配"></p><h2 id="go的内存分配核心思想"><a class="markdownIt-Anchor" href="#go的内存分配核心思想"></a> Go的内存分配核心思想</h2><p>Go是内置运行时的编程语言(<code>runtime</code>),像这种内置运行时的编程语言通常会抛弃传统的内存分配方式,改为自己管理。这样可以完成类似预分配、内存池等操作,以避开系统调用带来的性能问题,防止每次分配内存都需要系统调用。</p><p>用户线程的调度以及生命周期管理都是用户层面,Go语言自己实现的,不借助OS系统调用,减少系统资源消耗。</p><p>Go的内存分配的核心思想可以分为以下几点:</p><ul><li>每次从操作系统申请一大块儿的内存,由Go来对这块儿内存做分配,减少系统调用</li><li>内存分配算法采用Google的<a href="http://goog-perftools.sourceforge.net/doc/tcmalloc.html" target="_blank" rel="noopener">TCMalloc</a>算法。算法比较复杂,究其原理可自行查阅。其核心思想就是把内存切分的非常的细小,分为多级管理,以降低锁的粒度。</li><li>回收对象内存时,并没有将其真正释放掉,只是放回预先分配的大块内存中,以便复用。只有内存闲置过多的时候,才会尝试归还部分内存给操作系统,降低整体开销</li></ul><p>业界比较出名的内存分配器有Google的<code>tcmalloc</code>和Facebook的<code>jemalloc</code>。二者在避免内存碎片和性能上均比glic有比较大的优势,在多线程环境中效果更明显。</p><h2 id="程序在内存中的分布"><a class="markdownIt-Anchor" href="#程序在内存中的分布"></a> 程序在内存中的分布</h2><p><img src="https://webwlsong-1301722012.cos.ap-shanghai.myqcloud.com/mweb/2020/09/03/cheng-xu-nei-cun-yun-xing.jpg" alt="程序内存运行"></p><ul><li>代码段(<code>.text</code>),也称文本段(Text Segment),存放着程序的机器码和只读数据,可执行指令就是从这里取得的。如果可能,系统会安排好相同程序的多个运行实体共享这些实例代码。这个段在内存中一般被标记为只读,任何对该区的写操作都会导致段错误(Segmentation Fault)</li><li>数据段,包括已初始化的数据段(<code>.data</code>)和未初始化的数据段(<code>.bss</code>),前者用来存放保存全局的和静态的已初始化变量,后者用来保存全局的和静态的未初始化变量。数据段在编译时分配</li><li>堆栈段分为堆和栈:<ul><li><p>堆(<code>Heap</code>):用来存储程序运行时分配的变量。堆的大小并不固定,可动态扩张或缩减。其分配由malloc()、new()等这类实时内存分配函数来实现。当进程调用malloc等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);当利用free 等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减) 堆的内存释放由应用程序去控制,通常一个new()就要对应一个delete(),如果程序员没有释放掉,那么在程序结束后操作系统会自动回收。</p></li><li><p>栈(<code>Stack</code>)是一种用来存储函数调用时的临时信息的结构,如函数调用所传递的参数、函数的返回地址、函数的局部变量等。 在程序运行时由编译器在需要的时候分配,在不需要的时候自动清除。</p><p>栈的特性: 最后一个放入栈中的物体总是被最先拿出来,这个特性通常称为先进后出(FILO)队列。`<br>栈的基本操作: PUSH操作:向栈中添加数据,称为压栈,数据将放置在栈顶; POP操作:POP操作相反,在栈顶部移去一个元素,并将栈的大小减一,称为弹栈。</p></li></ul></li></ul><h2 id="堆和栈的区别"><a class="markdownIt-Anchor" href="#堆和栈的区别"></a> 堆和栈的区别</h2><ul><li><p>分配和管理方式不同 :</p><ul><li>堆是动态分配的,其空间的分配和释放都由程序员控制。</li><li>栈由编译器自动管理。栈有两种分配方式:静态分配和动态分配。<ul><li>静态分配由编译器完成,比如局部变量的分配。</li><li>动态分配由alloca()函数进行分配,但是栈的动态分配和堆是不同的,它的动态分配是由编译器进行释放,无须手工控制。</li></ul></li></ul></li><li><p>产生碎片不同</p><ul><li>对堆来说,频繁的new/delete或者malloc/free势必会造成内存空间的不连续,造成大量的碎片,使程序效率降低。</li><li>对栈而言,则不存在碎片问题,因为栈是先进后出的队列,永远不可能有一个内存块从栈中间弹出。</li></ul></li><li><p>生长方向不同</p><ul><li>堆是向着内存地址增加的方向增长的,从内存的低地址向高地址方向增长。</li><li>栈的生长方向与之相反,是向着内存地址减小的方向增长,由内存的高地址向低地址方向增长。</li></ul></li></ul><p>了解更多:</p><ol><li><a href="https://zhuanlan.zhihu.com/p/29216091" target="_blank" rel="noopener">图解TCMalloc</a> goole内存分配器</li><li><a href="https://blog.csdn.net/cxsydjn/article/details/79487805" target="_blank" rel="noopener">C/C++程序的5种内存存储区及示意</a></li></ol><p><em>参考文献:</em></p><ul><li><em>程序在内存中的分布 <a href="https://www.cnblogs.com/Lynn-Zhang/p/5449199.html" target="_blank" rel="noopener">https://www.cnblogs.com/Lynn-Zhang/p/5449199.html</a></em></li><li><em>从内存分配开始 <a href="https://mp.weixin.qq.com/s/EyWKFRu1xryoHY386QUcuA" target="_blank" rel="noopener">https://mp.weixin.qq.com/s/EyWKFRu1xryoHY386QUcuA</a></em></li><li><em>译文:Go 内存分配器可视化指南 <a href="https://www.linuxzen.com/go-memory-allocator-visual-guide.html" target="_blank" rel="noopener">https://www.linuxzen.com/go-memory-allocator-visual-guide.html</a></em></li><li><em>图解Go语言内存分配 <a href="https://juejin.im/post/5c888a79e51d456ed11955a8" target="_blank" rel="noopener">https://juejin.im/post/5c888a79e51d456ed11955a8</a></em></li><li><em>Golang源码探索(三) GC的实现原理 <a href="https://www.cnblogs.com/zkweb/p/7880099.html" target="_blank" rel="noopener">https://www.cnblogs.com/zkweb/p/7880099.html</a></em></li><li><em>《Go专家编程》Go 内存管理 <a href="https://my.oschina.net/renhc/blog/2236782?spm=a2c4e.10696291.0.0.a8e219a4hLvsZx" target="_blank" rel="noopener">https://my.oschina.net/renhc/blog/2236782?spm=a2c4e.10696291.0.0.a8e219a4hLvsZx</a></em></li><li><em>雨痕&lt;&lt;Go源码解析&gt;&gt;<br>go内存分配(英文) <a href="https://andrestc.com/post/go-memory-allocation-pt1/" target="_blank" rel="noopener">https://andrestc.com/post/go-memory-allocation-pt1/</a></em></li></ul>]]></content>
<summary type="html">
&lt;p&gt;go主要有以下五种内存存储区(c/c++也是一样):&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://webwlsong-1301722012.cos.ap-shanghai.myqcloud.com/mweb/2020/09/03/1599064164048.jpg&quot;
</summary>
<category term="go" scheme="https://webwlsong.gitee.io/categories/go/"/>
<category term="内存" scheme="https://webwlsong.gitee.io/categories/go/%E5%86%85%E5%AD%98/"/>
<category term="堆栈" scheme="https://webwlsong.gitee.io/categories/go/%E5%86%85%E5%AD%98/%E5%A0%86%E6%A0%88/"/>
<category term="go" scheme="https://webwlsong.gitee.io/tags/go/"/>
<category term="c" scheme="https://webwlsong.gitee.io/tags/c/"/>
<category term="c++" scheme="https://webwlsong.gitee.io/tags/c/"/>
<category term="内存" scheme="https://webwlsong.gitee.io/tags/%E5%86%85%E5%AD%98/"/>
<category term="堆栈" scheme="https://webwlsong.gitee.io/tags/%E5%A0%86%E6%A0%88/"/>
</entry>
<entry>
<title>DIY服务器搭建,内网穿透搭建</title>
<link href="https://webwlsong.gitee.io/2020/08/31/2020/2020-08/2020-08-31/"/>
<id>https://webwlsong.gitee.io/2020/08/31/2020/2020-08/2020-08-31/</id>
<published>2020-08-31T09:09:00.000Z</published>
<updated>2020-09-23T16:35:34.789Z</updated>
<content type="html"><![CDATA[<p>起初一直在用云服务器来搭自用服务器,为什么还要用自建一个服务器?</p><ul><li>云服务价格偏高性</li><li>性能达不到要求</li><li>IT人爱折腾,生命不止,学习不止</li></ul><h2 id="服务器选择"><a class="markdownIt-Anchor" href="#服务器选择"></a> 服务器选择</h2><ul><li>耗电量小</li><li>性价比高</li><li>噪声小(几乎没有噪声)<br>考虑过台式工作站服务器,NAS,最终选择mini电脑当自用服务器。</li></ul><h2 id="制作u盘linux启动盘"><a class="markdownIt-Anchor" href="#制作u盘linux启动盘"></a> 制作U盘Linux启动盘</h2><p>推荐使用工具rufus(推荐),UltraISO(不太推荐)<br>rufus做好启动盘之后,不需要修改卷标</p><ul><li>UltraIOS启动盘<br>U盘启动电脑进入安装界面</li></ul><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">vmlinuz  initrd=initrd.img  inst.stage2=hd:LABEL=CentOS\x207\x20x86_64 rd.live.check quiet   </span><br><span class="line">#这是按 Tab 键后的默认值;</span><br></pre></td></tr></table></figure><ul><li>rufus 启动<br><img src="https://static01.imgkr.com/temp/3ed79857352041c88cd07e5e2fa77697.png" alt="启动图片"></li></ul><p>通常ubuntu桌面和显卡驱动不兼容,导致安装完整之后进入不到桌面<br>解决方法:<br>1:更换桌面管理器<br>2:进入tty 按ctrl+alt+f2</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">sudo apt install lightdm</span><br><span class="line">sudo service lightdm restart</span><br></pre></td></tr></table></figure><p>默认启动多用户启动</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">sudo systemctl set-default multi-user.target</span><br><span class="line">#然后输入reboot命令重启:</span><br></pre></td></tr></table></figure><p>单次启动图形界面:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">sudo systemctl start graphical.target</span><br><span class="line">switchdesk GNOME&quot;,回车,再输入&quot;startx</span><br></pre></td></tr></table></figure><p>默认启动为图形界面:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">systemctl set-default graphical.target</span><br><span class="line">#然后执行reboot命令重启系统即可。</span><br></pre></td></tr></table></figure><h2 id="设置无线上网ubuntu20041是这个目录"><a class="markdownIt-Anchor" href="#设置无线上网ubuntu20041是这个目录"></a> 设置无线上网,Ubuntu20.04.1是这个目录</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">vim /etc/netplan/01-network-manager-all.yaml</span><br><span class="line">#添加</span><br><span class="line"> ethernets:</span><br><span class="line"> wlp1s0: #配置的网卡的名称</span><br><span class="line"> dhcp4: no #关闭DHCP,如果需要打开DHCP则写yes</span><br><span class="line"> dhcp6: no</span><br><span class="line"> addresses: [192.168.1.10/24] #配置的静态ip地址和掩码</span><br><span class="line"> gateway4: 192.168.1.1 #网关地址</span><br><span class="line"> nameservers:</span><br><span class="line"> addresses: [192.168.1.1,114.114.114.114] #DNS服务器地址,多个DNS服务器地址需要用英文逗号分隔开</span><br></pre></td></tr></table></figure><p>使其ip生效</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo netplan apply</span><br></pre></td></tr></table></figure><p>现在查看一下 IP是否生效</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ip addr 或者 ifconfig</span><br></pre></td></tr></table></figure><h2 id="frp内网穿透"><a class="markdownIt-Anchor" href="#frp内网穿透"></a> frp内网穿透</h2><p>设备清单:</p><ol><li>一台云主机</li><li>一台家用服务器</li></ol><p>frp 官方地址:<a href="https://github.com/fatedier/frp/" target="_blank" rel="noopener">https://github.com/fatedier/frp/</a><br>frp 中文文档:<a href="https://github.com/fatedier/frp/blob/dev/README_zh.md" target="_blank" rel="noopener">https://github.com/fatedier/frp/blob/dev/README_zh.md</a></p><p>我这里使用的是第三方,frpMgr极速安装包:<br><a href="https://github.com/Zo3i/frpMgr" target="_blank" rel="noopener">https://github.com/Zo3i/frpMgr</a><br>在云主机里面安装</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">wget -O - https://raw.githubusercontent.com/Zo3i/OCS/master/docker/docker-all2.sh | sh</span><br><span class="line">wget -O - https://raw.githubusercontent.com/Zo3i/frpMgr/master/web/src/main/docker/final/run.sh | sh</span><br></pre></td></tr></table></figure><p>安装完成登陆:<br>注:代码仅在Centos7,Debian9系统上通过测试</p><p>访问:你的服务器 ip:8999/frp 账号 admin 密码 12345678<br>查看日志命令:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">1. docker ps</span><br><span class="line">2. docker logs -f --tail 10 java项目的容器I</span><br></pre></td></tr></table></figure><p>如果需要修改代码,请自行编译 jar包重新部署即可…</p><p><img src="https://static01.imgkr.com/temp/58795ab06b954736ac04f3167e7a6290.jpg" alt="frp后台"></p><p>详细FRP快捷配置面板<br><a href="https://github.com/Zo3i/frpMgr/blob/master/README_zh.md" target="_blank" rel="noopener">https://github.com/Zo3i/frpMgr/blob/master/README_zh.md</a></p><p>启动,停止,重启frps服务</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">service frps status</span><br><span class="line">service frps stop</span><br><span class="line">service frps restart</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
&lt;p&gt;起初一直在用云服务器来搭自用服务器,为什么还要用自建一个服务器?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;云服务价格偏高性&lt;/li&gt;
&lt;li&gt;性能达不到要求&lt;/li&gt;
&lt;li&gt;IT人爱折腾,生命不止,学习不止&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;服务器选择&quot;&gt;&lt;a class=&quot;mar
</summary>
<category term="ubuntu" scheme="https://webwlsong.gitee.io/tags/ubuntu/"/>
<category term="linux" scheme="https://webwlsong.gitee.io/tags/linux/"/>
<category term="frp" scheme="https://webwlsong.gitee.io/tags/frp/"/>
<category term="内网穿透" scheme="https://webwlsong.gitee.io/tags/%E5%86%85%E7%BD%91%E7%A9%BF%E9%80%8F/"/>
</entry>
<entry>
<title>Ubuntu20.04.1关闭图形界面,使用tty登陆</title>
<link href="https://webwlsong.gitee.io/2020/08/30/2020/2020-08/2020-08-30-1/"/>
<id>https://webwlsong.gitee.io/2020/08/30/2020/2020-08/2020-08-30-1/</id>
<published>2020-08-30T03:08:00.000Z</published>
<updated>2020-09-23T16:35:34.789Z</updated>
<content type="html"><![CDATA[<h1 id="ubuntu-关闭图形界面使用tty登陆"><a class="markdownIt-Anchor" href="#ubuntu-关闭图形界面使用tty登陆"></a> Ubuntu 关闭图形界面,使用tty登陆</h1><p><a href="https://baike.baidu.com/item/TTY" target="_blank" rel="noopener">tty</a>是终端设备的统称,TeleTYpe的一个老缩写。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 关闭图形界面</span></span><br><span class="line">sudo systemctl <span class="built_in">set</span>-default multi-user.target</span><br><span class="line">sudo reboot</span><br><span class="line"><span class="comment"># 开启图形界面</span></span><br><span class="line">sudo systemctl <span class="built_in">set</span>-default graphical.target</span><br><span class="line">sudo reboot</span><br></pre></td></tr></table></figure><p>如果安装使用的是中文,字符显示乱码<br>安装zhcon</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo apt install zhcon</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
&lt;h1 id=&quot;ubuntu-关闭图形界面使用tty登陆&quot;&gt;&lt;a class=&quot;markdownIt-Anchor&quot; href=&quot;#ubuntu-关闭图形界面使用tty登陆&quot;&gt;&lt;/a&gt; Ubuntu 关闭图形界面,使用tty登陆&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://
</summary>
<category term="ubuntu" scheme="https://webwlsong.gitee.io/tags/ubuntu/"/>
<category term="linux" scheme="https://webwlsong.gitee.io/tags/linux/"/>
</entry>
<entry>
<title>更换了Hexo博客主题pure使用</title>
<link href="https://webwlsong.gitee.io/2020/08/29/2020/2020-08/2020-08-30/"/>
<id>https://webwlsong.gitee.io/2020/08/29/2020/2020-08/2020-08-30/</id>
<published>2020-08-29T16:00:00.000Z</published>
<updated>2020-09-23T16:35:34.789Z</updated>
<content type="html"><![CDATA[<h1 id="重新换了个清新的blog模版"><a class="markdownIt-Anchor" href="#重新换了个清新的blog模版"></a> 重新换了个清新的blog模版</h1><p><img src="https://webwlsong-1301722012.cos.ap-shanghai.myqcloud.com/mweb/2020/08/30/1598719074737.jpg" alt="1598719074737"></p><p>看着还不错,后续坚持分享更多有。欢迎大家留言</p>]]></content>
<summary type="html">
&lt;h1 id=&quot;重新换了个清新的blog模版&quot;&gt;&lt;a class=&quot;markdownIt-Anchor&quot; href=&quot;#重新换了个清新的blog模版&quot;&gt;&lt;/a&gt; 重新换了个清新的blog模版&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;https://webwlsong-13017220
</summary>
<category term="hexo" scheme="https://webwlsong.gitee.io/tags/hexo/"/>
<category term="pure" scheme="https://webwlsong.gitee.io/tags/pure/"/>
</entry>
<entry>
<title>基于微服务器 docker下的gitlab安装</title>
<link href="https://webwlsong.gitee.io/2020/08/28/2020/2020-08/2020-08-29/"/>
<id>https://webwlsong.gitee.io/2020/08/28/2020/2020-08/2020-08-29/</id>
<published>2020-08-28T16:00:00.000Z</published>
<updated>2020-09-23T16:35:34.789Z</updated>
<content type="html"><![CDATA[<h1 id="docker-gitlab安装"><a class="markdownIt-Anchor" href="#docker-gitlab安装"></a> docker gitlab安装</h1><p><img src="https://webwlsong-1301722012.cos.ap-shanghai.myqcloud.com/mweb/2020/08/29/oip3.jpeg" alt="OIP"></p><p>我是在开发机器上面安装</p><h2 id="第一步-在宿主机器上面安装创建gitlab配置目录"><a class="markdownIt-Anchor" href="#第一步-在宿主机器上面安装创建gitlab配置目录"></a> 第一步 在宿主机器上面安装创建gitlab配置目录</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mkdir -p /data/gitlab/&#123;config,logs,data&#125;</span><br></pre></td></tr></table></figure><h2 id="第二步-创建环境变量指向本地宿主机存储gitlab配置的目录"><a class="markdownIt-Anchor" href="#第二步-创建环境变量指向本地宿主机存储gitlab配置的目录"></a> 第二步 创建环境变量,指向本地宿主机存储gitlab配置的目录:</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">export GITLAB_HOME=/data/gitlab</span><br></pre></td></tr></table></figure><h2 id="第三步-运行镜像创建容器"><a class="markdownIt-Anchor" href="#第三步-运行镜像创建容器"></a> 第三步 运行镜像,创建容器:</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">docker run --detach \</span><br><span class="line">--hostname 127.0.0.1 \</span><br><span class="line">-p 8443:443 -p 8880:80 -p 8822:22 \</span><br><span class="line">--name gitlab --restart always \</span><br><span class="line">-v $GITLAB_HOME/config:/etc/gitlab \</span><br><span class="line">-v $GITLAB_HOME/logs:/var/log/gitlab \</span><br><span class="line">-v $GITLAB_HOME/data:/vat/opt/gitlab \</span><br><span class="line">gitlab/gitlab-ce:latest</span><br></pre></td></tr></table></figure><p>使用命令lsof -i 端口号 查看端口是否被使用<br>其中由于宿主机的22端口被sshd服务使用,所以改为映射8822端口。80端口被暂用了,改成8880<br>https 已经被占用了。</p><blockquote><p>注意: mac 1024一下的端口号需要 root权限</p></blockquote><hr><h2 id="第四步-配置gitlab"><a class="markdownIt-Anchor" href="#第四步-配置gitlab"></a> 第四步 配置gitlab</h2><ul><li>配置gitlab<br>容器生成后,根据需要修改gitlab的配置,直接进入宿主机本地映射的config目录,编辑gitlab.rb文件;</li><li>gitlab.rb文件内,主要需要配置的选项如下:</li></ul><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">## GitLab NGINX</span><br><span class="line">nginx[&apos;listen_port&apos;] = 80 # gitlab nginx 端口。默认端口为:80 </span><br><span class="line"> </span><br><span class="line">## GitLab Unicorn</span><br><span class="line">unicorn[&apos;listen&apos;] = &apos;localhost&apos;</span><br><span class="line">unicorn[&apos;port&apos;] = 8080 #默认是8080端口</span><br><span class="line"> </span><br><span class="line">## GitLab URL 配置http协议所使用的访问地址</span><br><span class="line">external_url GENERATED_EXTERNAL_URL&apos; # clone时显示的地址,gitlab 的域名</span><br><span class="line"> </span><br><span class="line"># 配置ssh协议所使用的访问地址和端口</span><br><span class="line">gitlab_rails[&apos;gitlab_ssh_host&apos;] = &apos;song.local&apos;</span><br><span class="line">gitlab_rails[&apos;gitlab_shell_ssh_port&apos;] = 8822</span><br></pre></td></tr></table></figure><ul><li>gitlab性能相关的选项如下:</li></ul><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"># 超时时间</span><br><span class="line">unicorn[&apos;worker_timeout&apos;] = 60 </span><br><span class="line"> </span><br><span class="line">#不能低于2,否则卡死 worker=CPU核数+1 </span><br><span class="line">unicorn[&apos;worker_processes&apos;] = 2</span><br><span class="line"> </span><br><span class="line"># 减少数据库缓存大小 默认256,可适当改小 </span><br><span class="line">postgresql[&apos;shared_buffers&apos;] = &quot;256MB&quot;</span><br><span class="line"> </span><br><span class="line"># 减少数据库并发数</span><br><span class="line">postgresql[&apos;max_worker_processes&apos;] = 8</span><br><span class="line"> </span><br><span class="line"># 减少sidekiq并发数</span><br><span class="line">sidekiq[&apos;concurrency&apos;] = 10</span><br><span class="line"> </span><br><span class="line"># 减少内存 </span><br><span class="line">unicorn[&apos;worker_memory_limit_min&apos;] = &quot;200 * 1 &lt;&lt; 20&quot;</span><br><span class="line">unicorn[&apos;worker_memory_limit_max&apos;] = &quot;300 * 1 &lt;&lt; 20&quot;</span><br></pre></td></tr></table></figure><ul><li>配置gitlab的邮箱服务:</li></ul><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">gitlab_rails[&apos;smtp_enable&apos;] = true</span><br><span class="line">gitlab_rails[&apos;smtp_address&apos;] = &quot;smtp.server&quot;</span><br><span class="line">gitlab_rails[&apos;smtp_port&apos;] = 465</span><br><span class="line">gitlab_rails[&apos;smtp_user_name&apos;] = &quot;smtp user&quot;</span><br><span class="line">gitlab_rails[&apos;smtp_password&apos;] = &quot;smtp password&quot;</span><br><span class="line">gitlab_rails[&apos;smtp_domain&apos;] = &quot;example.com&quot;</span><br><span class="line">gitlab_rails[&apos;smtp_authentication&apos;] = &quot;login&quot;</span><br><span class="line">gitlab_rails[&apos;smtp_enable_starttls_auto&apos;] = true</span><br><span class="line">gitlab_rails[&apos;smtp_openssl_verify_mode&apos;] = &apos;peer&apos;</span><br><span class="line"> </span><br><span class="line"># If your SMTP server does not like the default &apos;From: gitlab@localhost&apos; you</span><br><span class="line"># can change the &apos;From&apos; with this setting.</span><br><span class="line">gitlab_rails[&apos;gitlab_email_from&apos;] = &apos;gitlab@example.com&apos;</span><br><span class="line">gitlab_rails[&apos;gitlab_email_reply_to&apos;] = &apos;noreply@example.com&apos;</span><br></pre></td></tr></table></figure><ul><li>配置完成后,重启gitlab容器即可。</li></ul><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker restart ####</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
&lt;h1 id=&quot;docker-gitlab安装&quot;&gt;&lt;a class=&quot;markdownIt-Anchor&quot; href=&quot;#docker-gitlab安装&quot;&gt;&lt;/a&gt; docker gitlab安装&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;https://webwlsong-13017
</summary>
<category term="docker" scheme="https://webwlsong.gitee.io/tags/docker/"/>
<category term="gitlab" scheme="https://webwlsong.gitee.io/tags/gitlab/"/>
</entry>
<entry>
<title>php 基准测试对比。</title>
<link href="https://webwlsong.gitee.io/2017/05/31/2017-06-01/"/>
<id>https://webwlsong.gitee.io/2017/05/31/2017-06-01/</id>
<published>2017-05-31T16:00:00.000Z</published>
<updated>2020-09-23T16:35:34.789Z</updated>
<content type="html"><![CDATA[<p>php7 相比 Php5.6 提升 2-3 倍。<br>PHP7-JIT 相比 PHP5.6 提升 8 倍。</p><p>如果作为 php 开发者连鸟哥都不认识,起码不是很合格吧。下面是鸟哥做的测试对比。</p><p><img src="php.png" alt="php"></p><p>下面是鸟哥做的分享。</p><p><a href="https://www.slideshare.net/slideshow/embed_code/key/KMbqLBfzYnMN29" target="_blank" rel="noopener">为什么选择 php7?</a></p>]]></content>
<summary type="html">
&lt;p&gt;php7 相比 Php5.6 提升 2-3 倍。&lt;br&gt;
PHP7-JIT 相比 PHP5.6 提升 8 倍。&lt;/p&gt;
&lt;p&gt;如果作为 php 开发者连鸟哥都不认识,起码不是很合格吧。下面是鸟哥做的测试对比。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;php.png&quot; alt=&quot;p
</summary>
<category term="php" scheme="https://webwlsong.gitee.io/tags/php/"/>
<category term="php-jit" scheme="https://webwlsong.gitee.io/tags/php-jit/"/>
</entry>
<entry>
<title>operator mono vs fira code</title>
<link href="https://webwlsong.gitee.io/2017/05/26/2017-05-27/"/>
<id>https://webwlsong.gitee.io/2017/05/26/2017-05-27/</id>
<published>2017-05-26T16:00:00.000Z</published>
<updated>2020-09-23T16:35:34.789Z</updated>
<content type="html"><![CDATA[<p>operator mono 和 fira code 两个字体是目前世界上最好的字体。</p><p>1:看看别人的介绍</p><p><a href="https://medium.com/@peterpme/operator-mono-fira-code-the-best-of-both-worlds-191be512fd5e" target="_blank" rel="noopener">Operator Mono &amp; Fira Code — The Best of Both Worlds<br></a></p><p>2:Laravel作者 Eric L. Barnes用的也是这个字体。作者在推特上面发布出了他的配置</p><p><img src="laravel.png" alt="laravel"></p><p>3:<code>operator mono</code> 是收费字体。fira code是免费字体。<br>如果在mac 安装 <code>fira code</code> 可以使用命令</p><p><code>brew cask install font-fira-code</code><br>最后提供一个 operator mono下载地址<br>链接: <a href="https://pan.baidu.com/s/1nvynUXF" target="_blank" rel="noopener">https://pan.baidu.com/s/1nvynUXF</a> 密码: kezv</p><p>4:完成之后效果</p><p><img src="my.png" alt="my"></p>]]></content>
<summary type="html">
&lt;p&gt;operator mono 和 fira code 两个字体是目前世界上最好的字体。&lt;/p&gt;
&lt;p&gt;1:看看别人的介绍&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://medium.com/@peterpme/operator-mono-fira-code-the-best
</summary>
<category term="mono" scheme="https://webwlsong.gitee.io/categories/mono/"/>
<category term="operator" scheme="https://webwlsong.gitee.io/tags/operator/"/>
<category term="mono" scheme="https://webwlsong.gitee.io/tags/mono/"/>
<category term="fira" scheme="https://webwlsong.gitee.io/tags/fira/"/>
<category term="code" scheme="https://webwlsong.gitee.io/tags/code/"/>
</entry>
<entry>
<title>Nginx 限流</title>
<link href="https://webwlsong.gitee.io/2017/04/27/2017-04-28-1/"/>
<id>https://webwlsong.gitee.io/2017/04/27/2017-04-28-1/</id>
<published>2017-04-27T16:00:00.000Z</published>
<updated>2020-09-23T16:35:34.789Z</updated>
<content type="html"><![CDATA[<p>电商平台营销时候,经常会碰到的大流量问题,<br>除了做流量分流处理,可能还要做用户黑白名单、信誉分析,进而根据用户ip信誉权重做相应的流量拦截、限制流量。Nginx自身有的请求限制模块ngx_http_limit_req_module、流量限制模块ngx_stream_limit_conn_module基于令牌桶算法,可以方便的控制令牌速率,自定义调节限流,实现基本的限流控制。</p><p>对于提供下载的网站,肯定是要进行流量控制的,例如软件下载站、视频服务等。它也可以减少一些爬虫程序或者DDOS的攻击。</p><p>对这两个模块的介绍的文章也不少,这里转载一篇hopestar的文章: nginx限制IP连接数的范例参考, 因为他介绍的很简洁。</p><blockquote><p>如何Nginx限制同一个ip的连接数,限制并发数目:</p></blockquote><h2 id="1-限流"><a class="markdownIt-Anchor" href="#1-限流"></a> 1. 限流</h2><ul><li>添加limit_zone和limit_req_zone;<br>这个变量只能在http使用 :</li></ul><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">vi /export/servers/nginx/conf/nginx.conf </span><br><span class="line">limit_zone one <span class="variable">$binary_remote_addr</span> <span class="number">20</span>m;</span><br><span class="line">limit_req_zone <span class="variable">$binary_remote_addr</span> zone=req_one:<span class="number">20</span>m rate=<span class="number">12</span>r/s;</span><br></pre></td></tr></table></figure><ul><li>添加limit_conn 和limit_req</li></ul><p>这个变量可以在<code>http</code>, <code>server</code>, <code>location</code>使用 我是限制nginx上的所有服务,所以添加到http里面 (如果你需要限制部分服务,可在nginx/conf/domains里面选择相应的server或者location添加上便可)</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">vi /export/servers/nginx/conf/nginx.conf </span><br><span class="line">limit_zone one <span class="variable">$binary_remote_addr</span> <span class="number">20</span>m;</span><br><span class="line">limit_req_zone <span class="variable">$binary_remote_addr</span> zone=req_one:<span class="number">20</span>m rate=<span class="number">12</span>r/s;</span><br><span class="line">limit_conn one <span class="number">10</span>;</span><br><span class="line">limit_req zone=req_one burst=<span class="number">120</span>;</span><br></pre></td></tr></table></figure><p>参数详解(数值按具体需要和服务器承载能力设置,):</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">limit_zone,是针对每个变量(这里指IP,即<span class="variable">$binary_remote_addr</span>)定义一个存储session状态的容器。 </span><br><span class="line"> 这个示例中定义了一个<span class="number">20</span>m的容器,按照<span class="number">32</span>bytes/session, </span><br><span class="line"> 可以处理<span class="number">640000</span>个session。 </span><br><span class="line">limit_req_zone 与limit_zone类似。rate是请求频率. 每秒允许<span class="number">12</span>个请求。</span><br><span class="line">limit_conn one <span class="number">10</span> : 表示一个IP能发起<span class="number">10</span>个并发连接数</span><br><span class="line">limit_req: 与limit_req_zone对应。burst表示缓存住的请求数。</span><br></pre></td></tr></table></figure><p>示例:</p><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">http</span><br><span class="line">&#123;</span><br><span class="line"> <span class="attribute">limit_zone</span> one <span class="variable">$binary_remote_addr</span> <span class="number">20m</span>;</span><br><span class="line"> <span class="attribute">limit_req_zone</span> <span class="variable">$binary_remote_addr</span> zone=req_one:<span class="number">20m</span> rate=12r/s;</span><br><span class="line"> <span class="attribute">limit_conn</span> one <span class="number">10</span>;</span><br><span class="line"> <span class="attribute">limit_req</span> zone=req_one burst=<span class="number">120</span>;</span><br><span class="line"> <span class="section">server</span> &#123;</span><br><span class="line"> <span class="attribute">listen</span> <span class="number">80</span>;</span><br><span class="line"> <span class="attribute">server_name</span> status.xxx.com ;</span><br><span class="line"> <span class="attribute">location</span> / &#123;</span><br><span class="line"> <span class="attribute">stub_status</span> <span class="literal">on</span>;</span><br><span class="line"> <span class="attribute">access_log</span> <span class="literal">off</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>重启nginx</p><figure class="highlight vim"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">/export/servers/nginx/sbin/nginx -s reload</span><br></pre></td></tr></table></figure><h2 id="2-nginx白名单设置"><a class="markdownIt-Anchor" href="#2-nginx白名单设置"></a> 2. nginx白名单设置</h2><p>以上配置会对所有的ip都进行限制,有些时候我们不希望对搜索引擎的蜘蛛或者某些自己的代理机过来的请求进行限制, 对于特定的白名单ip我们可以借助geo指令实现。</p><p>先在nginx的请求日志进行统计,查看那个ip的访问量比较大, 运行:</p><figure class="highlight vim"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">cat</span> access.<span class="built_in">log</span> | <span class="keyword">grep</span> <span class="string">"03/Jun"</span> |awk <span class="string">'&#123;print $1&#125;'</span>|<span class="keyword">sort</span> |uniq -<span class="keyword">c</span>|<span class="keyword">sort</span> -nrk <span class="number">1</span>|head -n <span class="number">10</span></span><br><span class="line">#列出访问日志里面在<span class="number">6</span>月<span class="number">3</span>号这天前<span class="number">10</span>个访问量最大的ip.</span><br></pre></td></tr></table></figure><p>接下来就可以对这些IP进行分析了。看哪些需要进行白名单设置。</p><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">http</span><br><span class="line">&#123;</span><br><span class="line"> <span class="attribute">geo</span> <span class="variable">$limited</span> &#123; <span class="comment"># the variable created is $limited</span></span><br><span class="line"> <span class="attribute">default</span> <span class="number">1</span>;</span><br><span class="line"> 127.0.0.1/32 0;</span><br><span class="line"> 10.12.212.63 0;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="attribute">map</span> <span class="variable">$limited</span> <span class="variable">$limit</span> &#123;</span><br><span class="line"> 1 $binary_remote_addr;</span><br><span class="line"> 0 "";</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="attribute">limit_zone</span> one <span class="variable">$binary_remote_addr</span> <span class="number">20m</span>;</span><br><span class="line"> <span class="attribute">limit_req_zone</span> <span class="variable">$limit</span> zone=req_one:<span class="number">20m</span> rate=20r/s;</span><br><span class="line"> <span class="attribute">limit_conn</span> one <span class="number">10</span>;</span><br><span class="line"> <span class="attribute">limit_req</span> zone=req_one burst=<span class="number">120</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>上面两个需要用到map和geo模块,这是nginx自带的模块,有的运维喜欢把他们关闭,自己<code>./sbin/nginx -V</code> 留意一下。把配置的<code>--whithout-XXX-module</code>去掉重新编译一下就可以了。 上面这段配置的意思是:</p><p>geo指令定义了一个白名单<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mi>l</mi><mi>i</mi><mi>m</mi><mi>i</mi><mi>t</mi><mi>e</mi><mi>d</mi><mi mathvariant="normal">变</mi><mi mathvariant="normal">量</mi><mi mathvariant="normal">,</mi><mi mathvariant="normal">默</mi><mi mathvariant="normal">认</mi><mi mathvariant="normal">值</mi><mi mathvariant="normal">为</mi><mn>1</mn><mi mathvariant="normal">,</mi><mi mathvariant="normal">如</mi><mi mathvariant="normal">果</mi><mi mathvariant="normal">客</mi><mi mathvariant="normal">户</mi><mi mathvariant="normal">端</mi><mi>i</mi><mi>p</mi><mi mathvariant="normal">在</mi><mi mathvariant="normal">上</mi><mi mathvariant="normal">面</mi><mi mathvariant="normal">的</mi><mi mathvariant="normal">范</mi><mi mathvariant="normal">围</mi><mi mathvariant="normal">内</mi><mi mathvariant="normal">,</mi></mrow><annotation encoding="application/x-tex">limited变量,默认值为1,如果客户端ip在上面的范围内,</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathdefault" style="margin-right:0.01968em;">l</span><span class="mord mathdefault">i</span><span class="mord mathdefault">m</span><span class="mord mathdefault">i</span><span class="mord mathdefault">t</span><span class="mord mathdefault">e</span><span class="mord mathdefault">d</span><span class="mord cjk_fallback">变</span><span class="mord cjk_fallback">量</span><span class="mord cjk_fallback">,</span><span class="mord cjk_fallback">默</span><span class="mord cjk_fallback">认</span><span class="mord cjk_fallback">值</span><span class="mord cjk_fallback">为</span><span class="mord">1</span><span class="mord cjk_fallback">,</span><span class="mord cjk_fallback">如</span><span class="mord cjk_fallback">果</span><span class="mord cjk_fallback">客</span><span class="mord cjk_fallback">户</span><span class="mord cjk_fallback">端</span><span class="mord mathdefault">i</span><span class="mord mathdefault">p</span><span class="mord cjk_fallback">在</span><span class="mord cjk_fallback">上</span><span class="mord cjk_fallback">面</span><span class="mord cjk_fallback">的</span><span class="mord cjk_fallback">范</span><span class="mord cjk_fallback">围</span><span class="mord cjk_fallback">内</span><span class="mord cjk_fallback">,</span></span></span></span>limited的值为0<br>使用map指令映射搜索引擎客户端的ip为空串,如果不是搜索引擎就显示本身真实的ip,这样搜索引擎ip就不能存到limit_req_zone内存session中,所以不会限制搜索引擎的ip访问</p><h2 id="3-获取客户端的真实ip"><a class="markdownIt-Anchor" href="#3-获取客户端的真实ip"></a> 3. 获取客户端的真实IP</h2><p>顺带一提,为了获取客户端的真实IP。该模块需要安装read_ip模块,运维应该默认有安装。没有的话也可自行安装: 配置方式相当简单,重新编译 Nginx 加上 --with-http_realip_module 参数,如:</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">./configure -<span class="literal">-prefix</span>=/opt/nginx -<span class="literal">-with</span><span class="literal">-http_stub_status_module</span> -<span class="literal">-with</span><span class="literal">-pcre</span>=../pcre<span class="literal">-6</span>.<span class="number">6</span> -<span class="literal">-with</span><span class="literal">-http_realip_module</span></span><br><span class="line">make</span><br><span class="line">make install</span><br></pre></td></tr></table></figure><p>在server中增加:</p><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="attribute">set_real_ip_from</span> <span class="number">192.168.1.0</span>/<span class="number">24</span>;</span><br><span class="line"><span class="attribute">set_real_ip_from</span> <span class="number">192.168.2.1</span>;</span><br><span class="line"><span class="attribute">real_ip_header</span> [X-Real-IP|X-Forwarded-For];</span><br></pre></td></tr></table></figure><p>需要说明的地方就是设置IP源的时候可以设置单个IP,也可以设置IP段,另外是使用X-Real-IP还是X-Forwarded-For,取决于前面的服务器有哪个头。</p><p>set_real_ip_from 设置的IP端可以让运维查看日志,看下你的请求是来自哪些ip段。</p><p>重新加载一下服务,差不多就OK了。</p><p>再查看日志的话,应该可以看到客户端的真实IP了。</p><p>注意:如果未安装该模块的话你的获取到的IP端可能是来自前端代理(如squid)的IP,结果就是多个用户被当成单个用户对待,导致应用不能响应。</p><p>再PS一下: 自测: 有条件的自己可以用ab或者webben自测一下。</p><p>未安装前压测的话,因为有大量请求,所以access.log会有大量日志,而error.log日志没有变化。</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">➜ ~ webbench <span class="literal">-c</span> <span class="number">30</span> <span class="literal">-t</span> <span class="number">30</span> http://xxx.com</span><br><span class="line">Webbench - Simple Web Benchmark <span class="number">1.5</span></span><br><span class="line">Copyright (c) Radim Kolar <span class="number">1997</span><span class="literal">-2004</span>, GPL Open Source Software.</span><br><span class="line">Benchmarking: GET http://xxx.com </span><br><span class="line"><span class="number">30</span> clients, running <span class="number">30</span> sec.</span><br><span class="line">Speed=<span class="number">193468</span> pages/min, <span class="number">1254317</span> bytes/sec.</span><br><span class="line">Requests: <span class="number">96734</span> susceed, <span class="number">0</span> failed.</span><br></pre></td></tr></table></figure><p>安装后会发现很多超出的请求会返回503,所以access.log日志变化不快,error.log有大量记录,提示limit_reque缓住了多少请求。</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">➜ ~ webbench <span class="literal">-c</span> <span class="number">30</span> <span class="literal">-t</span> <span class="number">30</span> http://xxxx.com</span><br><span class="line">Webbench - Simple Web Benchmark <span class="number">1.5</span></span><br><span class="line">Copyright (c) Radim Kolar <span class="number">1997</span><span class="literal">-2004</span>, GPL Open Source Software.</span><br><span class="line">Benchmarking: GET http://xxx.com </span><br><span class="line"><span class="number">30</span> clients, running <span class="number">30</span> sec.</span><br><span class="line">Speed=<span class="number">120</span> pages/min, <span class="number">778</span> bytes/sec.</span><br><span class="line">Requests: <span class="number">60</span> susceed, <span class="number">0</span> failed.</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
&lt;p&gt;电商平台营销时候,经常会碰到的大流量问题,&lt;br&gt;
除了做流量分流处理,可能还要做用户黑白名单、信誉分析,进而根据用户ip信誉权重做相应的流量拦截、限制流量。Nginx自身有的请求限制模块ngx_http_limit_req_module、流量限制模块ngx_stream_
</summary>
<category term="nginx" scheme="https://webwlsong.gitee.io/tags/nginx/"/>
</entry>
<entry>
<title>Nginx 负载均衡策略</title>
<link href="https://webwlsong.gitee.io/2017/04/27/2017-04-28/"/>
<id>https://webwlsong.gitee.io/2017/04/27/2017-04-28/</id>
<published>2017-04-27T16:00:00.000Z</published>
<updated>2020-09-23T16:35:34.789Z</updated>
<content type="html"><![CDATA[<ol><li><p>轮询(默认)每个web请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">Upstream nginxDemo&#123;</span><br><span class="line"> server 127.0.0.1:8001;</span><br><span class="line"> server 127.0.0.1:8002;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li><li><p>最少链接web请求会被转发到连接数最少的服务器上。</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">Upstream nginxDemo&#123;</span><br><span class="line"> least_conn;</span><br><span class="line"> server 127.0.0.1:8001;</span><br><span class="line"> server 127.0.0.1:8002;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li><li><p>weight 权重指定轮询几率,weight和访问比率成正比,用 于后端服务器性能不均的情况,weight默认是1。</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">#服务器A和服务器B的访问比例:2-1;比如有3个请求,前两个会访问A,第三个会访问B,其他的归着和轮询一样。</span><br><span class="line"></span><br><span class="line">Upstream nginxDemo&#123;</span><br><span class="line"> least_conn;</span><br><span class="line"> server 127.0.0.1:8001;</span><br><span class="line"> server 127.0.0.1:8002;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li><li><p>ip_hash每个请求按访问ip的hash值分配,这样同一客户端连续的Web请求都会被分发到同一服务器进行处理,可以解决session的问题。当后台服务器宕机时,会自动跳转到其它服务器。基于weight的负载均衡和基于ip_hash的负载均衡可以组合在一起使用。</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">ip_hash;</span><br><span class="line">Upstream nginxDemo&#123;</span><br><span class="line"> server 127.0.0.1:8001 weight=2; #服务器A</span><br><span class="line"> server 127.0.0.1:8002; #服务器B</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li><li><p>url_hash(第三方)url_hash是nginx的第三方模块,nginx本身不支持,需要打补丁。nginx按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存服务器、文件服务器、静态服务器时比较有效。缺点是当后端服务器宕机的时候,url_hash不会自动跳转的其他缓存服务器,而是返回给用户一个503错误。</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">Upstream nginxDemo&#123;</span><br><span class="line"> server 127.0.0.1:8001 weight=2; #服务器A</span><br><span class="line"> server 127.0.0.1:8002; #服务器B</span><br><span class="line"> hash $request_url;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li><li><p>fair(第三方)按后端服务器的响应时间来分配请求,响应时间短的优先分配。</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">Upstream nginxDemo&#123;</span><br><span class="line"> server 127.0.0.1:8001 weight=2; #服务器A</span><br><span class="line"> server 127.0.0.1:8002; #服务器B</span><br><span class="line"> hair;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li></ol>]]></content>
<summary type="html">
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;轮询(默认)每个web请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。&lt;/p&gt;
&lt;figure class=&quot;highlight plain&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;sp
</summary>
<category term="nginx" scheme="https://webwlsong.gitee.io/categories/nginx/"/>
<category term="nginx" scheme="https://webwlsong.gitee.io/tags/nginx/"/>
</entry>
<entry>
<title>IntelliJ Idea 2017 免费激活方法</title>
<link href="https://webwlsong.gitee.io/2017/04/26/2017-04-27/"/>
<id>https://webwlsong.gitee.io/2017/04/26/2017-04-27/</id>
<published>2017-04-26T16:00:00.000Z</published>
<updated>2020-09-23T16:35:34.789Z</updated>
<content type="html"><![CDATA[<ol><li><p>第一种方法:<br>到网站 <a href="http://idea.lanyus.com/" target="_blank" rel="noopener">http://idea.lanyus.com/</a> 获取注册码。</p></li><li><p>第二种方法:<br>首先:<code>0.0.0.0 account.jetbrains.com</code> 添加到<code>hosts</code><br>填入下面的license server:</p></li></ol><p><a href="http://intellij.mandroid.cn/" target="_blank" rel="noopener">http://intellij.mandroid.cn/</a><br>  <a href="http://idea.imsxm.com/" target="_blank" rel="noopener">http://idea.imsxm.com/</a><br>  <a href="http://idea.iteblog.com/key.php" target="_blank" rel="noopener">http://idea.iteblog.com/key.php</a></p><p>以上方法验证均可以</p>]]></content>
<summary type="html">
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;第一种方法:&lt;br&gt;
到网站 &lt;a href=&quot;http://idea.lanyus.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://idea.lanyus.com/&lt;/a&gt; 获取注册码。&lt;/p&gt;
&lt;/li&gt;
&lt;l
</summary>
<category term="phpstrom" scheme="https://webwlsong.gitee.io/tags/phpstrom/"/>
<category term="jetbrains" scheme="https://webwlsong.gitee.io/tags/jetbrains/"/>
</entry>
<entry>
<title>php nodejs nginx 进程模型对比</title>
<link href="https://webwlsong.gitee.io/2017/04/24/2017-04-25/"/>
<id>https://webwlsong.gitee.io/2017/04/24/2017-04-25/</id>
<published>2017-04-24T16:00:00.000Z</published>
<updated>2020-09-23T16:35:34.789Z</updated>
<content type="html"><![CDATA[<h2 id="php-进程模型"><a class="markdownIt-Anchor" href="#php-进程模型"></a> PHP 进程模型</h2><p>PHP-FPM 是 PHP 针对 FastCGI 协议的具体实现,也是 PHP 在多种服务器端应用编程端口(SAPI:cgi、fast-cgi、cli、isapi、apache)里使用最普遍、性能最佳的一款进程管理器。</p><p>PHP-FPM 这种模型是非常典型的多进程同步模型,意味着一个请求对应一个进程线程,并且 IO 是同步阻塞的。所以尽管 PHP-FPM 维护着独立的 CGI 进程池、系统也可以很轻松的管理进程的生命周期,</p><p>受制于服务器的硬件设施,PHP-FPM 需要指定合理的 php-fpm.conf 配置:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">pm.max_children # 子进程最大数</span><br><span class="line">pm.start_servers # 启动时的子进程数</span><br><span class="line">pm.min_spare_servers # 最小空闲进程数,空闲进程不够时自动补充</span><br><span class="line">pm.max_spare_servers # 最大空闲进程数,空闲进程超过时自动清理</span><br><span class="line">pm.max_requests = 1000 # 子进程请求数阈值,超过后自动回收</span><br></pre></td></tr></table></figure><p>PHP 进程本身并不存在内存泄露的问题,每个进程完成请求处理后会回收内存,但是并不会释放给操作系统,这就导致大量内存被 PHP-FPM 占用而无法释放,请求量升高时性能骤降。</p><p>所以 PHP-FPM 需要控制单个子进程请求次数的阈值。很多人会误以为 max_requests 控制了进程的并发连接数,实际上 PHP-FPM 模式下的进程是单一线程的,请求无法并发。这个参数的真正意义是提供请求计数器的功能,超过阈值数目后自动回收,缓解内存压力。</p><h2 id="nginx进程模型"><a class="markdownIt-Anchor" href="#nginx进程模型"></a> nginx进程模型</h2><p>Nginx 是非阻塞IO &amp; IO复用模型,通过操作系统提供的类似 epoll 的功能,可以在一个线程里处理多个客户端的请求。<br>Nginx 的进程就是线程,即每个进程里只有一个线程,但这一个线程可以服务多个客户端。</p><p>nginx在启动后,会有一个master进程和多个worker进程。master进程主要用来管理worker进程,包含:接收来自外界的信号,向各worker进程发送信号,监控worker进程的运行状态,当worker进程退出后(异常情况下),会自动重新启动新的worker进程。而基本的网络事件,则是放在worker进程中来处理了。多个worker进程之间是对等的,他们同等竞争来自客户端的请求,各进程互相之间是独立的。一个请求,只可能在一个worker进程中处理,一个worker进程,不可能处理其它进程的请求。worker进程的个数是可以设置的,一般我们会设置与机器cpu核数一致,这里面的原因与nginx的进程模型以及事件处理模型是分不开的</p><p>因此才有了异步非阻塞的事件处理机制。具体到系统调用就是像select/poll/epoll/kqueue这样的系统调用。他们提供了一种机制,让你可以同时监控多个事件,调用他们是阻塞的,但可以设置超时时间,在超时时间之内,如果有事件准备好了,就返回。这种机制解决了我们上面两个问题。</p><p>以epoll为例:当事件没有准备好时,就放入epoll里面。如果有事件准备好了,那么就去处理;如果事件返回的是EAGAIN,那么继续将其放入epoll里面。从而,只要有事件准备好了,我们就去处理她,只有当所有时间都没有准备好时,才在epoll里面等着。这样,我们就可以并发处理大量的并发了,当然,这里的并发请求,是指未处理完的请求,线程只有一个,所以同时能处理的请求当然只有一个了,只是在请求间进行不断地切换而已,切换也是因为异步事件未准备好,而主动让出的。这里的切换是没有任何代价,你可以理解为循环处理多个准备好的事件,事实上就是这样的。</p><h2 id="nodejs-进程模型"><a class="markdownIt-Anchor" href="#nodejs-进程模型"></a> nodejs 进程模型</h2><p>我们都知道nodejs最大的特点就是单进程、无阻塞运行,并且是异步事件驱动的。Nodejs的这些特性能够很好的解决一些问题,例如在服务器开发中,并发的请求处理是个大问题,阻塞式的函数会导致资源浪费和时间延迟。通过事件注册、异步函数,开发人员可以提高资源的利用率,性能也会改善。既然Node.js采用单进程、单线程模式,那么在如今多核硬件流行的环境中,单核性能出色的Nodejs如何利用多核CPU呢?创始人Ryan Dahl建议,运行多个Nodejs进程,利用某些通信机制来协调各项任务。目前,已经有不少第三方的Node.js多进程支持模块发布,而NodeJS 0.6.x 以上的版本提供了一个cluster模块 ,允许创建“共享同一个socket”的一组进程,用来分担负载压力。</p>]]></content>
<summary type="html">
&lt;h2 id=&quot;php-进程模型&quot;&gt;&lt;a class=&quot;markdownIt-Anchor&quot; href=&quot;#php-进程模型&quot;&gt;&lt;/a&gt; PHP 进程模型&lt;/h2&gt;
&lt;p&gt;PHP-FPM 是 PHP 针对 FastCGI 协议的具体实现,也是 PHP 在多种服务器端应用编程端口(
</summary>
<category term="php" scheme="https://webwlsong.gitee.io/tags/php/"/>
<category term="nodejs" scheme="https://webwlsong.gitee.io/tags/nodejs/"/>
<category term="nginx" scheme="https://webwlsong.gitee.io/tags/nginx/"/>
</entry>
<entry>
<title>测试一下 qq和淘宝网页的测试</title>
<link href="https://webwlsong.gitee.io/2017/04/16/2017-04-17/"/>
<id>https://webwlsong.gitee.io/2017/04/16/2017-04-17/</id>
<published>2017-04-16T16:00:00.000Z</published>
<updated>2020-09-23T16:35:34.789Z</updated>
<content type="html"><![CDATA[<p>为什么做这个测试?最近有人你们的app接口能支持多大的并发,能支持多少的用户。<br>答: 这个本身就是个伪命题,没有场景话,很难回答。就好像,你们怎么做优化,这本身也是个伪命题。<br>如果要回答,网上google一下,有很多,问题在于你们的场景能用的到吗?如果要谈,这个很大的话题。<br>每个话题展开都能谈很久。</p><h2 id="延迟分析"><a class="markdownIt-Anchor" href="#延迟分析"></a> 延迟分析</h2><p>同城机房网络(0.5ms~2ms) max(1000qps)<br>jvm-gc(50ms左右) max(20qps)<br>如果是异地机房,例如北京到上海机房,一次网络往返可能就13~20毫秒延迟。max(50qps)</p><p>![测试图](2017-04-17 at 14.04.47.gif)<br>(测试图)</p>]]></content>
<summary type="html">
&lt;p&gt;为什么做这个测试?最近有人你们的app接口能支持多大的并发,能支持多少的用户。&lt;br&gt;
答: 这个本身就是个伪命题,没有场景话,很难回答。就好像,你们怎么做优化,这本身也是个伪命题。&lt;br&gt;
如果要回答,网上google一下,有很多,问题在于你们的场景能用的到吗?如果要谈,
</summary>
<category term="性能测试" scheme="https://webwlsong.gitee.io/tags/%E6%80%A7%E8%83%BD%E6%B5%8B%E8%AF%95/"/>
</entry>
<entry>
<title>docker ubuntu ping source 不能使用</title>
<link href="https://webwlsong.gitee.io/2016/11/27/2016-11-28/"/>
<id>https://webwlsong.gitee.io/2016/11/27/2016-11-28/</id>
<published>2016-11-27T16:00:00.000Z</published>
<updated>2020-09-23T16:35:34.789Z</updated>
<content type="html"><![CDATA[<h1 id="使用docker-拉取ubunut-镜像"><a class="markdownIt-Anchor" href="#使用docker-拉取ubunut-镜像"></a> 使用docker 拉取ubunut 镜像</h1><p>我本地使用的ubuntu 镜像版本如下:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">sh-4.3# cat /etc/issue</span><br><span class="line">Ubuntu 16.04.1 LTS \n \l</span><br><span class="line"></span><br><span class="line">sh-4.3#</span><br></pre></td></tr></table></figure><h2 id="拉取ubuntu进行你会发现有的镜像ping都不通"><a class="markdownIt-Anchor" href="#拉取ubuntu进行你会发现有的镜像ping都不通"></a> 拉取ubuntu进行,你会发现有的镜像Ping都不通</h2><p>解决方法: apt-get update 更新源</p><h2 id="source-和-ubunut的代码补全也不能使用"><a class="markdownIt-Anchor" href="#source-和-ubunut的代码补全也不能使用"></a> source 和 ubunut的代码补全也不能使用</h2><p>shell脚本中source 时提示 source: not found</p><p>Debian和Ubuntu中,/bin/sh默认已经指向dash,这是一个不同于bash的shell,它主要是为了执行脚本而出现,而不是交互,它速度更快,但功能相比bash要少很多,语法严格遵守POSIX标准</p><p>dash不是为交互而生的,所以我们在使用过程中还是习惯的修改成bash</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">ls -l /bin/sh </span><br><span class="line">显示 /bin/sh -&gt;dash </span><br><span class="line">显示使用的是dash</span><br></pre></td></tr></table></figure><p>修改默认的shell</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">sudo dpkg-reconfigure dash</span><br><span class="line"></span><br><span class="line">再次检查一下, ls /bin/sh -al 发现软链接指向/bin/bash</span><br></pre></td></tr></table></figure><h2 id="恢复ubuntu-bash下的自动补全"><a class="markdownIt-Anchor" href="#恢复ubuntu-bash下的自动补全"></a> 恢复ubuntu bash下的自动补全</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">1. 确认/etc/bash_completion是否存在,如果没有就安装一个:</span><br><span class="line">2. apt-get install bash-completion</span><br><span class="line">在用户的shell中运行:</span><br><span class="line">3. source /etc/bash_completion</span><br></pre></td></tr></table></figure><h2 id="添加新的用户-ubuntn下面"><a class="markdownIt-Anchor" href="#添加新的用户-ubuntn下面"></a> 添加新的用户 ubuntn下面</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">useradd -m username //ubuntu 自动创建用户目录</span><br><span class="line">passwd username //创建密码</span><br><span class="line">usermod -a -G sudo username //用户拥有权限</span><br><span class="line"></span><br><span class="line">ubuntu 默认的是dash shell</span><br><span class="line"></span><br><span class="line">修改成 bash</span><br><span class="line">vi /etc/passwd </span><br><span class="line">1.username:x:1000:1000::/home/username</span><br><span class="line">修成成如下:</span><br><span class="line">2. username:x:1000:1000::/home/username:/bin/bash</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
&lt;h1 id=&quot;使用docker-拉取ubunut-镜像&quot;&gt;&lt;a class=&quot;markdownIt-Anchor&quot; href=&quot;#使用docker-拉取ubunut-镜像&quot;&gt;&lt;/a&gt; 使用docker 拉取ubunut 镜像&lt;/h1&gt;
&lt;p&gt;我本地使用的ubuntu 镜像版本如
</summary>
<category term="ubuntu" scheme="https://webwlsong.gitee.io/tags/ubuntu/"/>
<category term="docker" scheme="https://webwlsong.gitee.io/tags/docker/"/>
</entry>
<entry>
<title>解决go delve 不能使用 OS X cannot get thread count</title>
<link href="https://webwlsong.gitee.io/2016/11/25/2016-11-26/"/>
<id>https://webwlsong.gitee.io/2016/11/25/2016-11-26/</id>
<published>2016-11-25T16:00:00.000Z</published>
<updated>2020-09-23T16:35:34.789Z</updated>
<content type="html"><![CDATA[<p>go Delve 报错</p><p>mac 解决方法如下:<br>我的go版本 :go version go1.7.3 darwin/amd64</p><p><a href="https://github.com/derekparker/delve/issues/645" target="_blank" rel="noopener">https://github.com/derekparker/delve/issues/645</a><br>`</p><ol><li>go into your GOPATH</li><li>create folder $GOPATH/src/github.com/derekparker/, and go into this folder.</li><li>‘cd $GOPATH/src/github.com/derekparker/’</li><li>git clone <a href="https://github.com/derekparker/delve.git" target="_blank" rel="noopener">https://github.com/derekparker/delve.git</a></li><li>cd delve</li><li>git fetch origin pull/665/head</li><li>git checkout FETCH_HEAD</li><li>CERT=dlv-cert make install<br>`</li></ol>]]></content>
<summary type="html">
&lt;p&gt;go Delve 报错&lt;/p&gt;
&lt;p&gt;mac 解决方法如下:&lt;br&gt;
我的go版本 :go version go1.7.3 darwin/amd64&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/derekparker/delve/issues/64
</summary>
<category term="go" scheme="https://webwlsong.gitee.io/tags/go/"/>
<category term="delve" scheme="https://webwlsong.gitee.io/tags/delve/"/>
</entry>
<entry>
<title>用swoole TCP Server 和mongodb做数据备份和恢复</title>
<link href="https://webwlsong.gitee.io/2016/05/18/mongo-php-error/"/>
<id>https://webwlsong.gitee.io/2016/05/18/mongo-php-error/</id>
<published>2016-05-18T10:52:40.000Z</published>
<updated>2020-09-23T16:35:34.805Z</updated>
<content type="html"><![CDATA[<p>应用场景是,单个用户写的数据是8-10条/S JSON数据包</p><p>采用架构如下图所示:<br><img src="Swoole-Mongo.png" alt="架构图"></p><p>采用的是</p><ul><li>php7.0.6</li><li>swoole-1.8.5版本</li><li>php扩展mongodb1.1.6 而目前mongo-1.6.14不支持php7 这样导致连接Mongo函数不一样,后面会讲到。</li><li>服务器 Ubuntu 14.04 64位 2核 4G</li><li>阿里云的Mongodb服务器</li></ul><p>到目前阿里云Mongodb还不支持sharding,后续会进行支持。目前是使用双节点。摘录<a href="https://yq.aliyun.com/articles/7557" target="_blank" rel="noopener">MongoDB杭州用户交流会</a>的一段话:</p><blockquote><p>阿里云目前已提供对MongoDB复制集(Replica Set)的支持,默认会为用户创建包含3个数据节点的复制集,其中一个Primary、一个Secondary,以及一个Hidden节点。Primary、Secondary对用户可见,用户可以自定义ReadPreference,Hidden节点对用户不可见,目前主要用于实例数据备份以及自动的failover,当有Primary或Secondary节点挂掉时,Hidden会被自动切换为Secondary,保证用户的服务不受影响。</p></blockquote><h3 id="mongodb服务器"><a class="markdownIt-Anchor" href="#mongodb服务器"></a> mongodb服务器</h3><p>阿里云服务器目前只支持ECS访问不支持外网方面</p><ul><li><p>[公网连接mongodb windows篇](<a href="https://help.aliyun.com/knowledge_detail/13052608.html#%E9%80%9A%E8%BF%87%E5%85%AC%E7%BD%91%E8%BF%9E%E6%8E%A5%E4%BA%91%E6%95%B0%E6%8D%AE%E5%BA%93MongoDB--ECS" target="_blank" rel="noopener">https://help.aliyun.com/knowledge_detail/13052608.html#通过公网连接云数据库MongoDB--ECS</a> Windows篇)</p></li><li><p>[公网连接mongodb linux篇](<a href="https://help.aliyun.com/knowledge_detail/13052572.html#%E9%80%9A%E8%BF%87%E5%85%AC%E7%BD%91%E8%BF%9E%E6%8E%A5%E4%BA%91%E6%95%B0%E6%8D%AE%E5%BA%93MongoDB--ECS" target="_blank" rel="noopener">https://help.aliyun.com/knowledge_detail/13052572.html#通过公网连接云数据库MongoDB--ECS</a> Linux篇)</p></li></ul><p>用如下命令检测是否连上mongodb</p><ul><li>ping <a href="http://dds-xxxxxxxx.mongodb.rds.aliyuncs.com" target="_blank" rel="noopener">dds-xxxxxxxx.mongodb.rds.aliyuncs.com</a></li><li>telnet <a href="http://dds-xxxxxxxxxxxx.mongodb.rds.aliyuncs.com" target="_blank" rel="noopener">dds-xxxxxxxxxxxx.mongodb.rds.aliyuncs.com</a> 3717</li><li>mongo --host <a href="http://dds-xxxxxxxxxxxxx1.mongodb.rds.aliyuncs.com:3717" target="_blank" rel="noopener">dds-xxxxxxxxxxxxx1.mongodb.rds.aliyuncs.com:3717</a> --authenticationDatabase admin -u root -p</li><li>mongo --host <a href="http://dds-xxxxxxxxxxxxxx2.mongodb.rds.aliyuncs.com:3717" target="_blank" rel="noopener">dds-xxxxxxxxxxxxxx2.mongodb.rds.aliyuncs.com:3717</a> --authenticationDatabase admin -u root -p</li></ul><p>如果本身server服务器用的ECS,还是要设置一下,</p><h3 id="搭建tcp-sever服务器"><a class="markdownIt-Anchor" href="#搭建tcp-sever服务器"></a> 搭建TCP-SEVER服务器</h3><ol><li>买好服务器之后习惯性的把服务器服务升级到最新。(这个是强迫症)</li></ol><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$ apt-get update </span><br><span class="line"></span><br><span class="line">$ apt-get upgrade</span><br></pre></td></tr></table></figure><ol start="2"><li>安装最新的php7.0.6环境</li></ol><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line">apt<span class="literal">-get</span> install python<span class="literal">-software</span><span class="literal">-properties</span></span><br><span class="line"></span><br><span class="line">apt<span class="literal">-get</span> install software<span class="literal">-properties</span><span class="literal">-common</span></span><br><span class="line"></span><br><span class="line">LC_ALL=C.UTF<span class="literal">-8</span> <span class="built_in">add-apt</span><span class="literal">-repository</span> ppa:ondrej/php</span><br><span class="line"></span><br><span class="line">apt<span class="literal">-get</span> update</span><br><span class="line"></span><br><span class="line">apt<span class="literal">-cache</span> show php7.<span class="number">0</span><span class="literal">-dev</span> </span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">Package: php7.<span class="number">0</span><span class="literal">-dev</span></span><br><span class="line">Source: php7.<span class="number">0</span></span><br><span class="line">Priority: optional</span><br><span class="line">Section: php</span><br><span class="line">Installed<span class="literal">-Size</span>: <span class="number">4658</span></span><br><span class="line">Maintainer: Debian PHP Maintainers &lt;pkg<span class="literal">-php</span><span class="literal">-maint</span>@lists.alioth.debian.org&gt;</span><br><span class="line">Architecture: amd64</span><br><span class="line">Version: <span class="number">7.0</span>.<span class="number">6</span><span class="literal">-12</span>+donate.sury.org~trusty+<span class="number">1</span></span><br><span class="line">Recommends: dh<span class="literal">-php</span>, pkg<span class="literal">-php</span><span class="literal">-tools</span></span><br><span class="line">Depends: autoconf (&gt;= <span class="number">2.63</span>), automake (&gt;= <span class="number">1.11</span>), libpcre3<span class="literal">-dev</span>, libssl<span class="literal">-dev</span>, php7.<span class="number">0</span><span class="literal">-cli</span> (&gt;= <span class="number">7.0</span>.<span class="number">6</span><span class="literal">-12</span>+donate.sury.org~trusty+<span class="number">1</span>), php7.<span class="number">0</span><span class="literal">-common</span> (= <span class="number">7.0</span>.<span class="number">6</span><span class="literal">-12</span>+donate.sury.org~trusty+<span class="number">1</span>), shtool, libtool</span><br><span class="line">Filename: pool/main/p/php7.<span class="number">0</span>/php7.<span class="number">0</span><span class="literal">-dev_7</span>.<span class="number">0.6</span><span class="literal">-12</span>+donate.sury.org~trusty+<span class="number">1</span>_amd64.deb</span><br><span class="line">Size: <span class="number">505784</span></span><br><span class="line">MD5sum: bb75fadf2fc0bae22d7a26999b9ac0e2</span><br><span class="line">SHA1: a85e13a259faae1377813d7b1e5c344c8ede8d09</span><br><span class="line">SHA256: <span class="number">79617</span>d3b79e054129a2e980534885ab794ec18c5052894e71d1da37ec07b2aff</span><br><span class="line">Description<span class="literal">-en</span>: Files <span class="keyword">for</span> PHP7.<span class="number">0</span> module development</span><br><span class="line"> This package provides the files from the PHP7.<span class="number">0</span> source needed <span class="keyword">for</span> compiling</span><br><span class="line"> additional modules.</span><br><span class="line"></span><br><span class="line">PHP (recursive acronym <span class="keyword">for</span> PHP: Hypertext Preprocessor) is a widely<span class="literal">-used</span></span><br><span class="line"> open source general<span class="literal">-purpose</span> scripting language that is especially suited</span><br><span class="line"> <span class="keyword">for</span> web development and can be embedded into HTML.</span><br><span class="line">Description<span class="literal">-md5</span>: cab4eaaf141b1f52bc2814eea2492ab2</span><br><span class="line"></span><br><span class="line">apt<span class="literal">-get</span> install php7.<span class="number">0</span><span class="literal">-dev</span></span><br></pre></td></tr></table></figure><ol start="3"><li>安装mongo扩展 和swoole扩展</li></ol><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line">使用pecl进行安装mongo和swoole扩展。</span><br><span class="line">这里记住是mongodb扩展不是mongo扩展。这两个扩展在使用上面不一样,后面会讲到。这里我们安装</span><br><span class="line">mongodb</span><br><span class="line"></span><br><span class="line">搜索mongodb</span><br><span class="line">$ pecl search mongo</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">pecl库更新到最新</span><br><span class="line">$ pecl channel-update pecl.php.net</span><br><span class="line"></span><br><span class="line">安装mongodb</span><br><span class="line">$ pecl install mongodb</span><br><span class="line"></span><br><span class="line">问题:</span><br><span class="line">1. 这里如果安装mongo会提示不支持Php7.0以上版本:</span><br><span class="line">pecl/mongo requires PHP (version &gt;= 5.3.0, version &lt;= 5.99.99),</span><br><span class="line">installed version is 7.0.6-12+donate.sury.org~trusty+1</span><br><span class="line">2. configure: error: Cannot find OpenSSL&apos;s libraries</span><br><span class="line"> 解决方法:  ln -s /usr/lib/x86_64-linux-gnu/libssl.so  /usr/lib</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">安装swoole</span><br><span class="line">$ pecl install swoole</span><br><span class="line"></span><br><span class="line">查找php.ini 把swoole.so和mongodb加入进去</span><br><span class="line">$ php --ini </span><br><span class="line"></span><br><span class="line">$ php -ri|grep swoole</span><br></pre></td></tr></table></figure><ol start="4"><li>PHP swoole代码</li></ol><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line">$serv = <span class="keyword">new</span> swoole_server(<span class="string">"0.0.0.0"</span>, <span class="number">9501</span>);</span><br><span class="line"></span><br><span class="line">$serv-&gt;set(<span class="keyword">array</span>(</span><br><span class="line"><span class="string">'worker_num'</span> =&gt; <span class="number">8</span>, <span class="comment">//工作进程数量</span></span><br><span class="line"><span class="string">'daemonize'</span> =&gt; <span class="keyword">false</span>, <span class="comment">//是否作为守护进程</span></span><br><span class="line">));</span><br><span class="line"></span><br><span class="line">$serv-&gt;on(<span class="string">'connect'</span>, <span class="function"><span class="keyword">function</span> <span class="params">($serv, $fd)</span> </span>&#123;</span><br><span class="line"><span class="keyword">echo</span> <span class="string">"Client:Connect.\n"</span>;</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">$serv-&gt;on(<span class="string">'receive'</span>, <span class="function"><span class="keyword">function</span> <span class="params">($serv,$fd, $from_id, $data)</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">$arr = json_decode($data);</span><br><span class="line"></span><br><span class="line"><span class="comment">//$array=array('column_name'=&gt;'col'.rand(100,999),'column_exp'=&gt;'xiaocai');</span></span><br><span class="line">$connection = <span class="keyword">new</span> MongoClient(<span class="string">"mongodb://root:密码@主机ID1.mongodb.rds.aliyuncs.com:3717,主机2.mongodb.rds.aliyuncs.com:3717/admin?replicaSet=副本集名称"</span>);</span><br><span class="line"><span class="comment">//$connection = new MongoClient("mongodb://localhost:27017");</span></span><br><span class="line">var_dump($connection);</span><br><span class="line">$roomid = <span class="string">"roomid"</span>.<span class="string">'_123'</span>;</span><br><span class="line">$collection = $connection-&gt;test-&gt;$roomid;</span><br><span class="line">$collection-&gt;insert($arr);</span><br><span class="line"></span><br><span class="line">$document = $collection-&gt;findOne();</span><br><span class="line">var_dump($document);</span><br><span class="line"></span><br><span class="line">$serv-&gt;send($fd, <span class="string">'Swoole: '</span> . $data);</span><br><span class="line">$serv-&gt;close($fd);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">$serv-&gt;on(<span class="string">'close'</span>, <span class="function"><span class="keyword">function</span> <span class="params">($serv, $fd)</span> </span>&#123;</span><br><span class="line"><span class="keyword">echo</span> <span class="string">"Client: Close.\n"</span>;</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">$serv-&gt;start();</span><br></pre></td></tr></table></figure><p>如果执行上面的代码的话,会报<code>PHP Fatal error: Uncaught Error: Class 'MongoClient' not found</code><br>这里要说明一下MongoClient是扩展Mongo的内置函数。<br>可以通过</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">print_r(get_declared_classes());</span><br></pre></td></tr></table></figure><p>查看函数列表<br>Mongo的函数列表</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line">[156] =&gt; MongoClient</span><br><span class="line">[157] =&gt; Mongo</span><br><span class="line">[158] =&gt; MongoDB</span><br><span class="line">[159] =&gt; MongoCollection</span><br><span class="line">[160] =&gt; MongoCursor</span><br><span class="line">[161] =&gt; MongoCommandCursor</span><br><span class="line">[162] =&gt; MongoGridFS</span><br><span class="line">[163] =&gt; MongoGridFSFile</span><br><span class="line">[164] =&gt; MongoGridFSCursor</span><br><span class="line">[165] =&gt; MongoWriteBatch</span><br><span class="line">[166] =&gt; MongoInsertBatch</span><br><span class="line">[167] =&gt; MongoUpdateBatch</span><br><span class="line">[168] =&gt; MongoDeleteBatch</span><br><span class="line">[169] =&gt; MongoId</span><br><span class="line">[170] =&gt; MongoCode</span><br><span class="line">[171] =&gt; MongoRegex</span><br><span class="line">[172] =&gt; MongoDate</span><br><span class="line">[173] =&gt; MongoBinData</span><br><span class="line">[174] =&gt; MongoDBRef</span><br><span class="line">[175] =&gt; MongoException</span><br><span class="line">[176] =&gt; MongoConnectionException</span><br><span class="line">[177] =&gt; MongoCursorException</span><br><span class="line">[178] =&gt; MongoCursorTimeoutException</span><br><span class="line">[179] =&gt; MongoGridFSException</span><br><span class="line">[180] =&gt; MongoResultException</span><br><span class="line">[181] =&gt; MongoWriteConcernException</span><br><span class="line">[182] =&gt; MongoDuplicateKeyException</span><br><span class="line">[183] =&gt; MongoExecutionTimeoutException</span><br><span class="line">[184] =&gt; MongoProtocolException</span><br><span class="line">[185] =&gt; MongoTimestamp</span><br><span class="line">[186] =&gt; MongoInt32</span><br><span class="line">[187] =&gt; MongoInt64</span><br><span class="line">[188] =&gt; MongoLog</span><br><span class="line">[189] =&gt; MongoPool</span><br><span class="line">[190] =&gt; MongoMaxKey</span><br><span class="line">[191] =&gt; MongoMinKey</span><br></pre></td></tr></table></figure><p>Mongodb的函数列表</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line">[100] =&gt; MongoDB\Driver\Command</span><br><span class="line"> [101] =&gt; MongoDB\Driver\Cursor</span><br><span class="line"> [102] =&gt; MongoDB\Driver\CursorId</span><br><span class="line"> [103] =&gt; MongoDB\Driver\Manager</span><br><span class="line"> [104] =&gt; MongoDB\Driver\Query</span><br><span class="line"> [105] =&gt; MongoDB\Driver\ReadConcern</span><br><span class="line"> [106] =&gt; MongoDB\Driver\ReadPreference</span><br><span class="line"> [107] =&gt; MongoDB\Driver\Server</span><br><span class="line"> [108] =&gt; MongoDB\Driver\BulkWrite</span><br><span class="line"> [109] =&gt; MongoDB\Driver\WriteConcern</span><br><span class="line"> [110] =&gt; MongoDB\Driver\WriteConcernError</span><br><span class="line"> [111] =&gt; MongoDB\Driver\WriteError</span><br><span class="line"> [112] =&gt; MongoDB\Driver\WriteResult</span><br><span class="line"> [113] =&gt; MongoDB\Driver\Exception\LogicException</span><br><span class="line"> [114] =&gt; MongoDB\Driver\Exception\RuntimeException</span><br><span class="line"> [115] =&gt; MongoDB\Driver\Exception\UnexpectedValueException</span><br><span class="line"> [116] =&gt; MongoDB\Driver\Exception\InvalidArgumentException</span><br><span class="line"> [117] =&gt; MongoDB\Driver\Exception\ConnectionException</span><br><span class="line"> [118] =&gt; MongoDB\Driver\Exception\AuthenticationException</span><br><span class="line"> [119] =&gt; MongoDB\Driver\Exception\SSLConnectionException</span><br><span class="line"> [120] =&gt; MongoDB\Driver\Exception\WriteException</span><br><span class="line"> [121] =&gt; MongoDB\Driver\Exception\BulkWriteException</span><br><span class="line"> [122] =&gt; MongoDB\Driver\Exception\ExecutionTimeoutException</span><br><span class="line"> [123] =&gt; MongoDB\Driver\Exception\ConnectionTimeoutException</span><br><span class="line"> [124] =&gt; MongoDB\BSON\Binary</span><br><span class="line"> [125] =&gt; MongoDB\BSON\Javascript</span><br><span class="line"> [126] =&gt; MongoDB\BSON\MaxKey</span><br><span class="line"> [127] =&gt; MongoDB\BSON\MinKey</span><br><span class="line"> [128] =&gt; MongoDB\BSON\ObjectID</span><br><span class="line"> [129] =&gt; MongoDB\BSON\Regex</span><br><span class="line"> [130] =&gt; MongoDB\BSON\Timestamp</span><br><span class="line"> [131] =&gt; MongoDB\BSON\UTCDateTime</span><br></pre></td></tr></table></figure><p>所以要使用Php7.0以上版本需要重新写连接mongdo的数据库<br>查找php文档<a href="http://php.net/manual/zh/set.mongodb.php" target="_blank" rel="noopener">Mongodb driver</a></p><p>修改成为mongodb的一个demo连接修改代码如下:</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br></pre></td><td class="code"><pre><span class="line">$serv = <span class="keyword">new</span> swoole_server(<span class="string">"0.0.0.0"</span>, <span class="number">9501</span>);</span><br><span class="line"></span><br><span class="line">$serv-&gt;set(<span class="keyword">array</span>(</span><br><span class="line"><span class="string">'worker_num'</span> =&gt; <span class="number">8</span>, <span class="comment">//工作进程数量</span></span><br><span class="line"><span class="string">'daemonize'</span> =&gt; <span class="keyword">false</span>, <span class="comment">//是否作为守护进程</span></span><br><span class="line">));</span><br><span class="line"></span><br><span class="line">$serv-&gt;on(<span class="string">'connect'</span>, <span class="function"><span class="keyword">function</span> <span class="params">($serv, $fd)</span> </span>&#123;</span><br><span class="line"><span class="keyword">echo</span> <span class="string">"Client:Connect.\n"</span>;</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">$serv-&gt;on(<span class="string">'receive'</span>, <span class="function"><span class="keyword">function</span> <span class="params">($serv, $fd, $from_id, $data)</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">$arr = json_decode($data);</span><br><span class="line"></span><br><span class="line">$bulk = <span class="keyword">new</span> MongoDB\Driver\BulkWrite([<span class="string">'ordered'</span> =&gt; <span class="keyword">true</span>]);</span><br><span class="line"></span><br><span class="line">$bulk-&gt;insert($arr);</span><br><span class="line"></span><br><span class="line">$connection = <span class="keyword">new</span> MongoDB\Driver\Manager(<span class="string">"mongodb://localhost:27017"</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">try</span> &#123;</span><br><span class="line"></span><br><span class="line">$result = $connection-&gt;executeBulkWrite(<span class="string">'test.roomid'</span>, $bulk);</span><br><span class="line"></span><br><span class="line">&#125; <span class="keyword">catch</span> (MongoDB\Driver\<span class="keyword">Exception</span>\BulkWriteException $e) &#123;</span><br><span class="line"></span><br><span class="line">$result = $e-&gt;getWriteResult();</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> ($writeConcernError = $result-&gt;getWriteConcernError()) &#123;</span><br><span class="line">printf(<span class="string">"%s (%d): %s\n"</span>,$writeConcernError-&gt;getMessage(),</span><br><span class="line">$writeConcernError-&gt;getCode(),</span><br><span class="line">var_export($writeConcernError-&gt;getInfo(), <span class="keyword">true</span>));</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// Check if any write operations did not complete at all</span></span><br><span class="line"><span class="keyword">foreach</span> ($result-&gt;getWriteErrors() <span class="keyword">as</span> $writeError) &#123;</span><br><span class="line">printf(<span class="string">"Operation#%d: %s (%d)\n"</span>,</span><br><span class="line">$writeError-&gt;getIndex(),</span><br><span class="line">$writeError-&gt;getMessage(),</span><br><span class="line">$writeError-&gt;getCode()</span><br><span class="line">);</span><br><span class="line">&#125;</span><br><span class="line">&#125; <span class="keyword">catch</span> (MongoDB\Driver\<span class="keyword">Exception</span>\<span class="keyword">Exception</span> $e) &#123;</span><br><span class="line">printf(<span class="string">"Other error: %s\n"</span>, $e-&gt;getMessage());</span><br><span class="line"><span class="keyword">exit</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">printf(<span class="string">"Inserted %d document(s)\n"</span>,$result-&gt;getInsertedCount());</span><br><span class="line">printf(<span class="string">"Updated %d document(s)\n"</span>,$result-&gt;getModifiedCount());</span><br><span class="line"></span><br><span class="line">$serv-&gt;send($fd, <span class="string">'Swoole: '</span> . $data);</span><br><span class="line"></span><br><span class="line">$serv-&gt;close($fd);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">$serv-&gt;on(<span class="string">'close'</span>, <span class="function"><span class="keyword">function</span> <span class="params">($serv, $fd)</span> </span>&#123;</span><br><span class="line"></span><br><span class="line"><span class="keyword">echo</span> <span class="string">"Client: Close.\n"</span>;</span><br><span class="line"></span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">$serv-&gt;start();</span><br></pre></td></tr></table></figure><p>模拟请求数据</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">netcat 127.0.0.1 9501</span><br></pre></td></tr></table></figure><p>END</p>]]></content>
<summary type="html">
&lt;p&gt;应用场景是,单个用户写的数据是8-10条/S JSON数据包&lt;/p&gt;
&lt;p&gt;采用架构如下图所示:&lt;br&gt;
&lt;img src=&quot;Swoole-Mongo.png&quot; alt=&quot;架构图&quot;&gt;&lt;/p&gt;
&lt;p&gt;采用的是&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;php7.0.6&lt;/li&gt;
&lt;li&gt;sw
</summary>
<category term="mongo" scheme="https://webwlsong.gitee.io/tags/mongo/"/>
<category term="php-mongo" scheme="https://webwlsong.gitee.io/tags/php-mongo/"/>
<category term="swoole" scheme="https://webwlsong.gitee.io/tags/swoole/"/>
<category term="tcp" scheme="https://webwlsong.gitee.io/tags/tcp/"/>
</entry>
<entry>
<title>go基本语法</title>
<link href="https://webwlsong.gitee.io/2016/04/28/go-sty01/"/>
<id>https://webwlsong.gitee.io/2016/04/28/go-sty01/</id>
<published>2016-04-28T07:25:02.000Z</published>
<updated>2020-09-23T16:35:34.805Z</updated>
<content type="html"><![CDATA[<h3 id="变量和赋值"><a class="markdownIt-Anchor" href="#变量和赋值"></a> 变量和赋值</h3><p>在go 语言中声明和赋值是分开的需要两步,也可以写成一步</p><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a <span class="keyword">int</span></span><br><span class="line"><span class="keyword">var</span> b <span class="keyword">bool</span></span><br><span class="line">a = <span class="number">5</span></span><br><span class="line">b = <span class="literal">false</span></span><br></pre></td></tr></table></figure><p>或者写成一步</p><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">a :=<span class="number">5</span></span><br><span class="line">b :=<span class="literal">false</span></span><br></pre></td></tr></table></figure><p>多个var声明可以成组</p><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span>(</span><br><span class="line">x <span class="keyword">int</span></span><br><span class="line">b <span class="keyword">bool</span></span><br><span class="line">)</span><br></pre></td></tr></table></figure><p>具备相同的类型多个变量可以在一行内完成声明:var x,y int 让x 和 y 都是<br>int 类型变量。同样也可以平行赋值</p><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">a,b := <span class="number">20</span>,<span class="number">16</span></span><br></pre></td></tr></table></figure><p>这样让a和b的值分别是20和16</p><p>一些特殊的变量名是_(下划线)。标示任何赋值给他的都会抛弃掉。<br>例如:</p><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">_,b :=<span class="number">1</span>,<span class="number">2</span></span><br></pre></td></tr></table></figure><p>这样抛弃掉1 把b赋值为2.</p><h3 id="数字类型number"><a class="markdownIt-Anchor" href="#数字类型number"></a> 数字类型(Number)</h3><p>数值类型有三种,一种是<code>整数类型</code>,另外一种是<code>浮点型</code>,<br>还有一种是<code>虚数类型</code>。正整数和零统称为: <code>无符号整型</code>,<br>而负整数称为: <code>有符号整型</code>。</p><p>无符号类型能够表示正整数和零。而有符号类型除了能够表示正整数和零外,还可以表示负整数。</p><p>另外还有一些别名类型,比如byte类型,这个类型和uint8是一样的,表示字节类型。另外一个是rune类型,这个类型和int32是一样的,用来表示unicode的代码点,就是unicode字符所对应的整数。</p><p>Go还定义了三个依赖系统的类型,uint,int和uintptr。因为在32位系统和64位系统上用来表示这些类型的位数是不一样的。</p><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">对于<span class="number">32</span>位系统</span><br><span class="line"><span class="keyword">uint</span>=<span class="keyword">uint32</span></span><br><span class="line"><span class="keyword">int</span>=<span class="keyword">int32</span></span><br><span class="line"><span class="keyword">uintptr</span>为<span class="number">32</span>位的指针</span><br><span class="line">对于<span class="number">64</span>位系统</span><br><span class="line"><span class="keyword">uint</span>=<span class="keyword">uint64</span></span><br><span class="line"><span class="keyword">int</span>=<span class="keyword">int64</span></span><br><span class="line"><span class="keyword">uintptr</span>为<span class="number">64</span>位的指针</span><br></pre></td></tr></table></figure><p>至于类型后面跟的数字8,16,32或是64则表示用来表示这个类型的位不同,位越多,能表示的整数范围越大。</p><p>比如对于用N位来表示的整数,如果是有符号的整数,能够表示的整数范围为-2^(N-1) ~ 2^(N-1)-1;如果是无符号的整数,则能表示的整数范围为0 ~ 2^(N-1)。</p><p>Go的浮点数类型有两种,<code>float32</code>和<code>float64</code>。float32又叫单精度浮点型,float64又叫做双精度浮点型。其最主要的区别就是小数点后面能跟的小数位数不同.</p><p>另外Go还有两个其他语言所没有的类型,虚数类型。complex64和complex128。</p><p>对于数值类型,其所共有的操作为加法(+),减法(-),乘法(*)和除法(/)。另外对于整数类型,还定义了求余运算(%)</p><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> main</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> (</span><br><span class="line"> <span class="string">"fmt"</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line"> <span class="keyword">var</span> a <span class="keyword">float64</span> = <span class="number">12</span></span><br><span class="line"> <span class="keyword">var</span> b <span class="keyword">float64</span> = <span class="number">3</span></span><br><span class="line"></span><br><span class="line"> fmt.Println(a % b)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
&lt;h3 id=&quot;变量和赋值&quot;&gt;&lt;a class=&quot;markdownIt-Anchor&quot; href=&quot;#变量和赋值&quot;&gt;&lt;/a&gt; 变量和赋值&lt;/h3&gt;
&lt;p&gt;在go 语言中声明和赋值是分开的需要两步,也可以写成一步&lt;/p&gt;
&lt;figure class=&quot;highlight go&quot;&gt;&lt;
</summary>
<category term="go" scheme="https://webwlsong.gitee.io/categories/go/"/>
<category term="golang" scheme="https://webwlsong.gitee.io/categories/go/golang/"/>
<category term="go" scheme="https://webwlsong.gitee.io/tags/go/"/>
<category term="golang" scheme="https://webwlsong.gitee.io/tags/golang/"/>
</entry>
<entry>
<title>架构设计图</title>
<link href="https://webwlsong.gitee.io/2016/04/21/hw-jg/"/>
<id>https://webwlsong.gitee.io/2016/04/21/hw-jg/</id>
<published>2016-04-21T09:51:31.000Z</published>
<updated>2020-09-23T16:35:34.805Z</updated>
<content type="html"><![CDATA[<p>今天抽点时间把产品架构图给画出来了。<br><img src="hw_jg.png" alt="产品架构图"></p>]]></content>
<summary type="html">
&lt;p&gt;今天抽点时间把产品架构图给画出来了。&lt;br&gt;
&lt;img src=&quot;hw_jg.png&quot; alt=&quot;产品架构图&quot;&gt;&lt;/p&gt;
</summary>
<category term="架构" scheme="https://webwlsong.gitee.io/tags/%E6%9E%B6%E6%9E%84/"/>
</entry>
<entry>
<title>创业公司入职3年小结</title>
<link href="https://webwlsong.gitee.io/2016/04/20/ranyao-chuangye/"/>
<id>https://webwlsong.gitee.io/2016/04/20/ranyao-chuangye/</id>
<published>2016-04-20T14:07:23.000Z</published>
<updated>2020-09-23T16:35:34.805Z</updated>
<content type="html"><![CDATA[<p>在创业公司3年多,学到了很多东西,也历练了很多,也见识了很多,后面会专门写几篇关于我在创业公司经历,大致从产品迭代开发,创业公司喜欢什么类型的人才,怎么在创业公司工作几个方面来介绍。本篇主要是入职3年小结</p><h4 id="我们的产品在使用和用过那些技术"><a class="markdownIt-Anchor" href="#我们的产品在使用和用过那些技术"></a> 我们的产品在使用和用过那些技术</h4><ul><li>服务器端:PHP语言</li><li>数据库:MYSQL</li><li>缓存 redis memcache</li><li>Android: Android原生</li><li>IOS: Object-c, Swift</li><li>PC: c# WPF MVVM</li><li>流媒体: C,C++ SRS和自建RTMP-server,webRTC</li><li>服务器:阿里云云服务 (20+台)</li><li>云存储: 七牛</li><li>第三方厂家:云信IM和短信,SendCloud(邮件)极光推送(消息)Openfire, bugtags,友盟,支付支付和微信支付</li><li>后面想到在补充</li></ul><h4 id="入职的第一年"><a class="markdownIt-Anchor" href="#入职的第一年"></a> 入职的第一年</h4><p>2013年2-3月份开始着手做教育产品,往往产品模型和软件架构是密切相关的,第一年我们只做了Android Pad,是一个大而全的产品封闭性的产品。起初软硬件都打算做的,先从软件做起,那个时候开模没有100W都很难做。所以当时公司经理和技术总监决定从软件开始做起,做了仿launcher,里面可以嵌入自己的App,其他的厂家的App,类似一个Android Rom的一个东西。当时做了及时问和考试苑。那个时候我主要负责服务器端开发,负责服务器基础架构,技术选型,服务器端人员招聘等工作。说白了,就是一个主程序员。</p><p>是否使用云服务器还是仔细斟酌考虑,采用自购服务器托管(当时主流),还是用云服务器。通过测试几家云服务器商(Ucloud,AWS,阿里云),最终选择了阿里云,即使当时有很多对云服务器有很多谩骂声,但是针对我们小企业来说,云服务器是个不二的选择,至今我们都认为是正确的选择。这里还有个小插曲,我们在通宵测试对比Ucloud,那天晚上他们服务器正好升级,白忙活了。<br>云存储MFS的年代,当时也测试对比又拍云和七牛还有阿里云的OSS存储。</p><h4 id="入职第二年"><a class="markdownIt-Anchor" href="#入职第二年"></a> 入职第二年</h4><p>公司经理和技术总监离职,大股东进入,因为表现比较好,转升为技术总监。产品方向转向做移动App。还是以Android Pad为主,实现双向互动。我们也从小的办公场地搬到一个大的办公场地,开始了招兵买马。陆陆续续 流媒体组,测试组,设计组也细化开来分成UI和UE。流媒体部分还从做监控行业找到一个从业10来年经验的一个同事(却为后面埋下祸根)。由8-9个研发团队翻了了一倍,15-16个<br>这一年我们做了很多基础架构方面的事情,jenkins集成发布和测试,使用jenkins打包android。由原生git管理,迁移到gitlab,使用git flow 去管理。我也由ubuntu转成MAC平台开发。把云存储由阿里云OSS转向到七牛。(这个上周阿里云过来拜访来提到这个事情,起初对OSS不是很重视,出了很多问题).那一年我们还完善了考试苑web端的开发,以及移动的考试苑api,和当时梯子网类似,同时还上了微课集模块,也已经在着手做教育云盘。<br>这一年我们公司也做了几次大的活动,包括和一些其他公司合作共赢开发,资源互换等尝试。这一年我们又有一次深刻的通宵经历,全司通宵修改版本,为第二天发布会做准备。虽然很辛苦,但是还是很快乐。<br>这一年我们还开始认识到手机应该是主流,同时要启动ios的开发。这一年结束之后不是很理想,陆续有人提出离职。也是这一年开始了解Docker方面的。</p><h4 id="入职第三年"><a class="markdownIt-Anchor" href="#入职第三年"></a> 入职第三年</h4><p>这一年最苦的时候服务器端只剩下我一人,同年5月我们获得了中信证券,银河证券 A轮 3000W的融资,后期慢慢有把这个团队重新组建起来,在后来我就从服务器端退出来,交给一个PHP资深的同事负责(英语比国语说的好 在互联网10来年经验的人),这一年服务器端进行了一次架构升级,同年我们开始从内部选拔人员转做IOS开发,组建IOS组,从Android和流媒体组自愿转岗到IOS,有一个经验非常丰富的同时带领,也是我招聘进来最得意的一位同事,技术非常全面。也是天天动听比较早期的员工。经历过创业和在大公司是完全不同的人。<br>流媒体也从原来的只支持Android,向全端支持,进行一次架构升级。Android端也进行了一次软件架构的升级。<br>为了优化书写感知,同年8月我们启动PC版本的开发。B/S和C/S架构上面抉择,最终我们选择了C/S架构的PC端。主要是考虑到和第三方手写板兼容性更好,B/S架构还的需求写插件支持才可以。<br>起初没有人会开发C/S或者我们在这个方面都没有经验,现在做WPF或者WCF的人少之又少,采用外包的方式。后面发现作为公司的产品外包是根本行不通,在产品不断的要进行修改,外包根本满足不了我们的需求。最后还的重新组建PC团队。补充流媒体团队的实力,流媒体中间件人员,主要做流媒体和M的对接工作。版本比较的多,测试人员我们也的扩充。研发团队扩展到目前团队23人。<br>后面公司也收购了一个市场团队。专做市场推广。</p><p>先写到这里吧</p>]]></content>
<summary type="html">
&lt;p&gt;在创业公司3年多,学到了很多东西,也历练了很多,也见识了很多,后面会专门写几篇关于我在创业公司经历,大致从产品迭代开发,创业公司喜欢什么类型的人才,怎么在创业公司工作几个方面来介绍。本篇主要是入职3年小结&lt;/p&gt;
&lt;h4 id=&quot;我们的产品在使用和用过那些技术&quot;&gt;&lt;a cl
</summary>
</entry>
</feed>
1
https://gitee.com/webwlsong/webwlsong.git
git@gitee.com:webwlsong/webwlsong.git
webwlsong
webwlsong
webwlsong
master

搜索帮助