<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Apocalypse</title>
  
  
  <link href="/atom.xml" rel="self"/>
  
  <link href="http://lougazen.github.io/"/>
  <updated>2021-03-26T08:58:19.429Z</updated>
  <id>http://lougazen.github.io/</id>
  
  <author>
    <name>LouGaZen</name>
    
  </author>
  
  <generator uri="http://hexo.io/">Hexo</generator>
  
  <entry>
    <title>gorm.v2升级备忘</title>
    <link href="http://lougazen.github.io/2021/03/25/gorm-v2%E5%8D%87%E7%BA%A7%E5%A4%87%E5%BF%98/"/>
    <id>http://lougazen.github.io/2021/03/25/gorm-v2升级备忘/</id>
    <published>2021-03-25T03:01:33.000Z</published>
    <updated>2021-03-26T08:58:19.429Z</updated>
    
    <content type="html"><![CDATA[<h2 id="序"><a href="#序" class="headerlink" title="序"></a>序</h2><p><a href="https://gorm.io/zh_CN/" target="_blank" rel="noopener">GORM v2</a>发布半年有余，因为有太多破坏性变更，目前现有的项目都不敢贸贸然进行升级。恰逢最近新启动一个小项目，遂打算是用新版的gorm，为以后的升级提供一些参考。</p><h2 id="变更"><a href="#变更" class="headerlink" title="变更"></a>变更</h2><h3 id="外键"><a href="#外键" class="headerlink" title="外键"></a>外键</h3><p>v1版在处理关联对象时默认不会创建外键，创建外键需要显式在tag里声明。</p><p>升级后的v2默认会给关联的对象创建外键。如果需要跟v1保持一致，需要手动配置</p><figure class="highlight golang"><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">db, err := gorm.Open(mysql.Open(dsn), &amp;gorm.Config&#123;</span><br><span class="line">DisableForeignKeyConstraintWhenMigrating: <span class="literal">true</span>,</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure><h3 id="datetime精度"><a href="#datetime精度" class="headerlink" title="datetime精度"></a>datetime精度</h3><p>v1版datetime精度默认是0（秒），v2版默认是3（毫秒），配置方式：</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">db, err = gorm.Open(mysql.New(mysql.Config&#123;</span><br><span class="line">DSN: dsn,</span><br><span class="line">DisableDatetimePrecision: true,</span><br><span class="line">&#125;), nil)</span><br></pre></td></tr></table></figure><p>因为我使用的时间戳是是13位，所以这里没跟v1保持一致</p><h3 id="sql连接池"><a href="#sql连接池" class="headerlink" title="sql连接池"></a>sql连接池</h3><p>v1版的sql连接池可以直接通过<code>db.DB()</code>方法直接获取，v2则同时会返回一个err，需要单独处理</p><h3 id="log输出"><a href="#log输出" class="headerlink" title="log输出"></a>log输出</h3><p>v1版可以通过<code>db.LogMode(true)</code>在日志里输出每一条sql语句，v2里没有了这个方法，取而代之的是根据log level进行输出</p><figure class="highlight golang"><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">db, err := gorm.Open(mysql.Open(dsn), &amp;gorm.Config&#123;</span><br><span class="line">Logger: logger.Default.LogMode(logger.Info),</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure><p>或</p><figure class="highlight golang"><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">db, err := gorm.Open(mysql.Open(dsn), <span class="literal">nil</span>)</span><br><span class="line">db = db.Debug()</span><br></pre></td></tr></table></figure><p>使用下来发现日志详细程度会比v1更高</p><h3 id="RecordNotFound"><a href="#RecordNotFound" class="headerlink" title="RecordNotFound"></a>RecordNotFound</h3><p>v1版自带<code>gorm.IsErrRecordNotFound(err)</code>方法判断，升级v2后不再提供这个方法，需要改成<code>errors.Is(err, gorm.ErrRecordNotFound)</code></p><h2 id="鸣谢"><a href="#鸣谢" class="headerlink" title="鸣谢"></a>鸣谢</h2><blockquote><p><a href="https://gorm.io/zh_CN/docs/v2_release_note.html" target="_blank" rel="noopener">GORM 2.0 发布说明</a></p></blockquote>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h2 id=&quot;序&quot;&gt;&lt;a href=&quot;#序&quot; class=&quot;headerlink&quot; title=&quot;序&quot;&gt;&lt;/a&gt;序&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;https://gorm.io/zh_CN/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;GORM v2&lt;/a
      
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>记一次kubernetes节点内存占用过高问题排查</title>
    <link href="http://lougazen.github.io/2021/03/08/%E8%AE%B0%E4%B8%80%E6%AC%A1kubernetes%E8%8A%82%E7%82%B9%E5%86%85%E5%AD%98%E5%8D%A0%E7%94%A8%E8%BF%87%E9%AB%98%E9%97%AE%E9%A2%98%E6%8E%92%E6%9F%A5/"/>
    <id>http://lougazen.github.io/2021/03/08/记一次kubernetes节点内存占用过高问题排查/</id>
    <published>2021-03-08T08:44:42.000Z</published>
    <updated>2021-03-08T09:37:54.906Z</updated>
    
    <content type="html"><![CDATA[<h2 id="序"><a href="#序" class="headerlink" title="序"></a>序</h2><p>公司的应用服务通过kubernetes集群部署的，集群包含5个节点。最近其中一节点占用一直维持95%，遂进行问题排查。</p><h2 id="问题排查"><a href="#问题排查" class="headerlink" title="问题排查"></a>问题排查</h2><h3 id="容器的问题？"><a href="#容器的问题？" class="headerlink" title="容器的问题？"></a>容器的问题？</h3><p>首先先把该机器设置为”不可调度”（防止后续操作死灰复燃），然后将部分内存占用高的调度到其他机器上（如nginx-ingress）</p><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="https://cdn.jsdelivr.net/gh/LouGaZen/image-hosting@upic/uPic/YU8FVn.png" alt="收效甚微" title="">                </div>                <div class="image-caption">收效甚微</div>            </figure><p>内存确实降下来了（一点点😅），起码先不用频繁触发报警</p><h3 id="kubernetes的问题？"><a href="#kubernetes的问题？" class="headerlink" title="kubernetes的问题？"></a>kubernetes的问题？</h3><p>因为节点是购买自阿里云的ECS，且这些节点无法远程登录，排查工作一度暂停。后来换用了<a href="https://k8slens.dev" target="_blank" rel="noopener">Lens</a>对集群进行管理后发现可以轻松登录节点进行操作了。</p><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="https://cdn.jsdelivr.net/gh/LouGaZen/image-hosting@upic/uPic/dZ69hU.png" alt="Lens - Nodes" title="">                </div>                <div class="image-caption">Lens - Nodes</div>            </figure><p>进入shell之后执行<code>top</code>命令然后按大写<code>M</code>查看内存占用最高的服务，看到了<code>rsyslogd</code>（当时忘了截图了）</p><p>Google了一番后得知rsyslog是日志收集服务，主要是通过以下文件收集</p><table><thead><tr><th>路径</th><th>描述</th></tr></thead><tbody><tr><td>/var/log/messages</td><td>服务信息日志(记录linux操作系统常见的服务信息和错误信息)</td></tr><tr><td>/var/log/secure</td><td>系统的登陆日志(记录用户和工作组的变化情况,是系统安全日志，用户的认证登陆情况</td></tr><tr><td>/var/log/maillog</td><td>邮件日志</td></tr><tr><td>/var/log/cron</td><td>定时任务</td></tr><tr><td>/var/log/boot.log</td><td>系统启动日志</td></tr></tbody></table><p>然后<code>tail -f /var/log/messages</code>一下，好家伙，日志一直刷刷刷的跑</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></pre></td><td class="code"><pre><span class="line">kubelet_volumes.go:128] Orphaned pod &quot;***&quot; found, but volume paths are still present on disk. : There were a total of 1 errors similar to this.  Turn up verbosity to see them.</span><br><span class="line">...</span><br><span class="line">systemd[1]: Scope libcontainer-***-systemd-test-default-dependencies.scope has no PIDs. Refusing.</span><br><span class="line">systemd[1]: Scope libcontainer-***-systemd-test-default-dependencies.scope has no PIDs. Refusing.</span><br><span class="line">systemd[1]: Created slice libcontainer_***_systemd_test_default.slice.</span><br><span class="line">systemd[1]: Removed slice libcontainer_***_systemd_test_default.slice.</span><br><span class="line">systemd[1]: Created slice libcontainer_***_systemd_test_default.slice.</span><br><span class="line">systemd[1]: Removed slice libcontainer_***_systemd_test_default.slice.</span><br></pre></td></tr></table></figure><p>（大致恢复了事故现场，截图丢了）</p><p>再Google一番后里面这里有两个问题待解决</p><h4 id="僵尸Pod"><a href="#僵尸Pod" class="headerlink" title="僵尸Pod"></a>僵尸Pod</h4><p>出现<code>Orphaned pod &quot;***&quot; found</code>就是僵尸Pod的问题了，一般是因为删除容器的时候没删干净，导致配置文件残留在节点机器上，k8s就会不断尝试给它复活但是基本上会复活失败</p><p>进入<code>/var/lib/kubelet/***</code>，然后<code>cat etc-host</code>看一下该容器的名字，然后去<code>kubectl get pods | grep （容器名字）</code>看是否还在（一般都是不在的了）</p><p>然后对文件夹进行删除（如有mount volume之类的要先unmount，我这里没有mount所以可以直接删掉）</p><p>好了，现在看日志就没有kubelet_volumes.go的报错了</p><h4 id="内置container组件问题"><a href="#内置container组件问题" class="headerlink" title="内置container组件问题"></a>内置container组件问题</h4><p>看这里的描述<a href="https://latiaoder.com/post/kubernetes/%E9%97%AE%E9%A2%98%E5%A4%84%E7%90%86.html" target="_blank" rel="noopener">k8s 问题处理</a>似乎是container版本过旧或者不兼容，按他的说法去更新一下就好了</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">rpm -Uvh https://download.docker.com/linux/centos/7/x86_64/edge/Packages/containerd.io-1.2.10-3.2.el7.x86_64.rpm</span><br></pre></td></tr></table></figure><p>如果是用Lens去登录节点的话更新过程会断开连接，不要慌，过一会而就能重连了。</p><h3 id="执下手尾"><a href="#执下手尾" class="headerlink" title="执下手尾"></a>执下手尾</h3><p>处理完后看看<code>tail -f /var/log/messages</code>，此时没有疯狂刷日志了，但<code>rsyslogd</code>的内存占用还没下来，遂进行网管必备的重启大法</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">systemd restart rsyslog.service</span><br></pre></td></tr></table></figure><p>此时再看top，内存占用最高的不是它了</p><p>再去阿里云的监控看看，内存占用暴跌至正常水平😄</p><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="https://cdn.jsdelivr.net/gh/LouGaZen/image-hosting@upic/uPic/4k4dP0.png" alt="会心一击" title="">                </div>                <div class="image-caption">会心一击</div>            </figure><h2 id="鸣谢"><a href="#鸣谢" class="headerlink" title="鸣谢"></a>鸣谢</h2><blockquote><p><a href="https://sunsea.im/rsyslogd-systemd-journald-high-memory-solution.html" target="_blank" rel="noopener">rsyslogd、systemd-journald内存占用高解决方案</a><br><a href="https://developer.aliyun.com/article/688719" target="_blank" rel="noopener">挂载失败-日志中显示僵尸pod的问题</a><br><a href="https://cloud.tencent.com/developer/article/1385911" target="_blank" rel="noopener">k8s关于Orphaned pod found - but volume paths are still present on disk的处理</a><br><a href="https://latiaoder.com/post/kubernetes/%E9%97%AE%E9%A2%98%E5%A4%84%E7%90%86.html" target="_blank" rel="noopener">k8s 问题处理</a></p></blockquote>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h2 id=&quot;序&quot;&gt;&lt;a href=&quot;#序&quot; class=&quot;headerlink&quot; title=&quot;序&quot;&gt;&lt;/a&gt;序&lt;/h2&gt;&lt;p&gt;公司的应用服务通过kubernetes集群部署的，集群包含5个节点。最近其中一节点占用一直维持95%，遂进行问题排查。&lt;/p&gt;
&lt;h2 id=&quot;问题
      
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>golang简单websocket demo及nginx转发事要</title>
    <link href="http://lougazen.github.io/2020/03/04/golang%E7%AE%80%E5%8D%95websocket-demo%E5%8F%8Anginx%E8%BD%AC%E5%8F%91%E4%BA%8B%E8%A6%81/"/>
    <id>http://lougazen.github.io/2020/03/04/golang简单websocket-demo及nginx转发事要/</id>
    <published>2020-03-04T11:57:25.000Z</published>
    <updated>2020-03-04T12:44:39.205Z</updated>
    
    <content type="html"><![CDATA[<h2 id="序"><a href="#序" class="headerlink" title="序"></a>序</h2><p>最近一个项目上用到消息推送功能，boss说写个简单的ws让前端自行处理消息就好（前端：MMP）。<br>看到网上用到比较多的框架是<a href="https://github.com/gorilla/websocket" target="_blank" rel="noopener">gorilla/websocket</a>，但是要验证第三方包的稳定性还是需要一定时间，还是用官方的websocket包吧（又不是不能用.jpg）。<br>思路其实很简单，一端接收到消息之后直接推入一个channel。另启一个协程去接收这个channel的消息，然后广播到所有ws连接。</p><h2 id="Code"><a href="#Code" class="headerlink" title="Code"></a>Code</h2><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><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><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</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">"context"</span></span><br><span class="line">    <span class="string">"log"</span></span><br><span class="line">    <span class="string">"net/http"</span></span><br><span class="line">    <span class="string">"sync"</span></span><br><span class="line"></span><br><span class="line">    <span class="string">"golang.org/x/net/websocket"</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> (</span><br><span class="line">    <span class="comment">// WsSrv -</span></span><br><span class="line">    WsSrv *WsServer</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> (</span><br><span class="line">    <span class="comment">// MessageChanSize -</span></span><br><span class="line">    MessageChanSize = <span class="number">1024</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="comment">// WsServer -</span></span><br><span class="line"><span class="keyword">type</span> WsServer <span class="keyword">struct</span> &#123;</span><br><span class="line">    Clients     <span class="keyword">map</span>[<span class="keyword">string</span>]*WsClient</span><br><span class="line">    MessageChan <span class="keyword">chan</span> <span class="keyword">string</span></span><br><span class="line">    Codec       websocket.Codec</span><br><span class="line">    sync.RWMutex</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// ClientConn -</span></span><br><span class="line"><span class="keyword">type</span> WsClient <span class="keyword">struct</span> &#123;</span><br><span class="line">    websocket *websocket.Conn</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// InitWsServer -</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">InitWsServer</span><span class="params">()</span></span> &#123;</span><br><span class="line">    WsSrv = &amp;WsServer&#123;</span><br><span class="line">        Clients:     <span class="keyword">map</span>[<span class="keyword">string</span>]*WsClient&#123;&#125;,</span><br><span class="line">        MessageChan: <span class="built_in">make</span>(<span class="keyword">chan</span> <span class="keyword">string</span>, MessageChanSize),</span><br><span class="line">        Codec:       websocket.Message,</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// WsReceiver -</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">WsReceiver</span><span class="params">(ws *websocket.Conn)</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> (</span><br><span class="line">        msg <span class="keyword">string</span></span><br><span class="line">        err error</span><br><span class="line">    )</span><br><span class="line">    <span class="keyword">defer</span> <span class="function"><span class="keyword">func</span><span class="params">()</span></span> &#123;</span><br><span class="line">        <span class="keyword">if</span> err = ws.Close(); err != <span class="literal">nil</span> &#123;</span><br><span class="line">            log.Printf(<span class="string">"[WsReceiver] ws(%v) closed err: %v\n"</span>, ws.RemoteAddr(), err)</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;()</span><br><span class="line"></span><br><span class="line">    userID := ws.Request().URL.Query().Get(<span class="string">"user_id"</span>)</span><br><span class="line">    <span class="keyword">if</span> userID == <span class="string">""</span> &#123;</span><br><span class="line">        <span class="keyword">return</span></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">defer</span> <span class="function"><span class="keyword">func</span><span class="params">()</span></span> &#123;</span><br><span class="line">        WsSrv.Lock()</span><br><span class="line">        <span class="keyword">defer</span> WsSrv.Unlock()</span><br><span class="line">        <span class="built_in">delete</span>(WsSrv.Clients, userID)</span><br><span class="line">    &#125;()</span><br><span class="line"></span><br><span class="line">    WsSrv.Lock()</span><br><span class="line">    WsSrv.Clients[userID] = &amp;WsClient&#123;websocket: ws&#125;</span><br><span class="line">    WsSrv.Unlock()</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> err = WsSrv.Codec.Receive(ws, &amp;msg); err != <span class="literal">nil</span> &#123;</span><br><span class="line">            log.Printf(<span class="string">"[WsReceiver] receive from remote result err: %v\n"</span>, err)</span><br><span class="line">            <span class="keyword">return</span></span><br><span class="line">        &#125;</span><br><span class="line">        WsSrv.MessageChan &lt;- msg</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// WsSender -</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">WsSender</span><span class="params">(ctx context.Context)</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> err error</span><br><span class="line">    <span class="keyword">for</span> &#123;</span><br><span class="line">        <span class="keyword">select</span> &#123;</span><br><span class="line">        <span class="keyword">case</span> msg := &lt;-WsSrv.MessageChan:</span><br><span class="line">            <span class="keyword">for</span> userID, conn := <span class="keyword">range</span> WsSrv.Clients &#123;</span><br><span class="line">                <span class="keyword">if</span> err = websocket.Message.Send(conn.websocket, msg); err != <span class="literal">nil</span> &#123;</span><br><span class="line">                    log.Printf(<span class="string">"[WsSender] send msg(%v) to user_id(%v) result err: %v\n"</span>, msg, userID, err)</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        <span class="keyword">case</span> &lt;-ctx.Done():</span><br><span class="line">            <span class="keyword">return</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</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> err error</span><br><span class="line"></span><br><span class="line">    InitWsServer()</span><br><span class="line">    <span class="keyword">go</span> WsSender(context.Background())</span><br><span class="line"></span><br><span class="line">    mux := http.NewServeMux()</span><br><span class="line">    mux.Handle(<span class="string">"/im"</span>, websocket.Handler(WsReceiver))</span><br><span class="line">    mux.HandleFunc(<span class="string">"/ping"</span>, <span class="function"><span class="keyword">func</span><span class="params">(writer http.ResponseWriter, request *http.Request)</span></span> &#123;</span><br><span class="line">        _, _ = writer.Write([]<span class="keyword">byte</span>(<span class="string">"pong"</span>))</span><br><span class="line">    &#125;)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> err = http.ListenAndServe(<span class="string">":23333"</span>, mux); err != <span class="literal">nil</span> &#123;</span><br><span class="line">        log.Fatalln(err)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="nginx转发事要"><a href="#nginx转发事要" class="headerlink" title="nginx转发事要"></a>nginx转发事要</h2><p>在http请求升级为ws请求的过程中会带着两个重要的header，一个是<code>Upgrade: websocket</code>，另一个是<code>Connection: upgrade</code>。只有带上这两个header才能在http/1.1下成功将http请求升级为ws请求，但是如果在服务器中有nginx反向代理的情况下往往会把这个头丢掉，所以要在配置文件上加上来，否则会出现著名的<a href="https://zh.wikipedia.org/wiki/HTTP%E7%8A%B6%E6%80%81%E7%A0%81" target="_blank" rel="noopener">http状态码400</a>错误</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><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="attribute">map</span> <span class="variable">$http_upgrade</span> <span class="variable">$connection_upgrade</span> &#123;</span><br><span class="line">    <span class="attribute">default</span> upgrade;</span><br><span class="line">    "" close;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="attribute">upstream</span> srv &#123;</span><br><span class="line">    <span class="attribute">server</span> <span class="number">127.0.0.1:23333</span>;</span><br><span class="line">&#125;</span><br><span class="line"></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><br><span class="line">    <span class="attribute">location</span> <span class="regexp">~ ^/im</span> &#123;</span><br><span class="line">        <span class="attribute">proxy_pass</span> http://srv;</span><br><span class="line">        <span class="attribute">proxy_http_version</span> <span class="number">1</span>.<span class="number">1</span>;</span><br><span class="line">        <span class="attribute">proxy_set_header</span> Upgrade <span class="variable">$http_upgrade</span>;</span><br><span class="line">        <span class="attribute">proxy_set_header</span> Connection <span class="variable">$connection_upgrade</span>;</span><br><span class="line">        <span class="attribute">proxy_set_header</span> Host <span class="variable">$host</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="鸣谢"><a href="#鸣谢" class="headerlink" title="鸣谢"></a>鸣谢</h2><blockquote><p><a href="https://blog.csdn.net/yxw2014/article/details/24317993" target="_blank" rel="noopener">golang websocket的例子</a><br><a href="https://www.nginx.com/blog/websocket-nginx/" target="_blank" rel="noopener">Using NGINX as a WebSocket Proxy</a><br><a href="http://www.easyswoole.com/wstool.html" target="_blank" rel="noopener">websocket 在线测试工具</a><br><a href="https://www.npmjs.com/package/wscat" target="_blank" rel="noopener">wscat</a></p></blockquote>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h2 id=&quot;序&quot;&gt;&lt;a href=&quot;#序&quot; class=&quot;headerlink&quot; title=&quot;序&quot;&gt;&lt;/a&gt;序&lt;/h2&gt;&lt;p&gt;最近一个项目上用到消息推送功能，boss说写个简单的ws让前端自行处理消息就好（前端：MMP）。&lt;br&gt;看到网上用到比较多的框架是&lt;a href=&quot;
      
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>iPhone 5s降级iOS 10.3.3简要备忘</title>
    <link href="http://lougazen.github.io/2020/03/02/iPhone-5s%E9%99%8D%E7%BA%A7iOS-10-3-3%E7%AE%80%E8%A6%81%E5%A4%87%E5%BF%98/"/>
    <id>http://lougazen.github.io/2020/03/02/iPhone-5s降级iOS-10-3-3简要备忘/</id>
    <published>2020-03-02T05:04:07.000Z</published>
    <updated>2020-03-02T05:53:24.235Z</updated>
    
    <content type="html"><![CDATA[<h2 id="序"><a href="#序" class="headerlink" title="序"></a>序</h2><p>好像好久都没有更新博客了，还是要养成做记录的习惯。</p><p>偶然看到5s可以降级iOS 10.3.3的帖子，二话不说GKD。中途遇到一些问题在此做个备忘</p><h2 id="准备"><a href="#准备" class="headerlink" title="准备"></a>准备</h2><p> 1.一台正常运行的iPhone 5s<br> 2.macOS with python3 environment<br> 3.科学上网</p><h2 id="正式开始"><a href="#正式开始" class="headerlink" title="正式开始"></a>正式开始</h2><p> 1.到<a href="https://github.com/MatthewPierson/Vieux" target="_blank" rel="noopener">https://github.com/MatthewPierson/Vieux</a>把降级脚本克隆下来，然后去<a href="https://ipsw.me" target="_blank" rel="noopener">https://ipsw.me</a>下载对应型号的iOS 10.3.3固件到脚本所在目录<br> 2.执行<code>sudo pip3 install -r requirement.txt</code>安装所需包（可能需要科学上网）<br> 3.手机连上电脑进入DFU模式（如何进入DFU可以看<a href="https://zh.ifixit.com/Guide/iPhone+4+-+4S+-+5+-+5S+-+5c+-+6+-+6S+-+%E5%A6%82%E4%BD%95%E5%9C%A8DFU%E6%A8%A1%E5%BC%8F%E5%88%B7%E6%9C%BA%E3%80%82%E5%AF%86%E7%A0%81%E6%81%A2%E5%A4%8D%E3%80%82/28229" target="_blank" rel="noopener">这里</a>）<br> 3.执行<code>sudo python3 vieux -i ➕上固件所在路径</code><br> 4.等待脚本撞bug。按照漏洞发现者的说法这个漏洞并不是100%成功，没有撞成功重试即可，成功的标志是手机闪一下绿屏。绿屏过后就会自己恢复10.3.3固件</p><p> <img src="https://i.loli.net/2020/03/02/tKhObEuIjQLPqM1.png" alt="降级成功"></p><h2 id="奇难杂症"><a href="#奇难杂症" class="headerlink" title="奇难杂症"></a>奇难杂症</h2><h3 id="No-Module-Found"><a href="#No-Module-Found" class="headerlink" title="No Module Found"></a>No Module Found</h3><p> 这个我是感觉最坑爹的地方，pip3安装说成功，<code>pip3 list</code>也有list出来，但是执行的时候却报错，一看<code>pip3 --version</code>下巴都掉了</p><p> <img src="https://i.loli.net/2020/03/02/TraXm5hLEo34j89.png" alt="pip3 --version"></p> <figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="https://i.loli.net/2020/03/02/p5olFN8YBrPxDZ9.png" alt="坑" title="">                </div>                <div class="image-caption">坑</div>            </figure><p> 爬了一下google，发现pip的命令可以用<code>python3 -m pip ...</code>代替，所以上述第二步的安装环境可以执行<code>sudo python3 -m pip install -r requirements.txt</code></p><h3 id="No-Backend-Available"><a href="#No-Backend-Available" class="headerlink" title="No Backend Available"></a>No Backend Available</h3><p> 这个一开始以为是包的问题，用pip install补上后发现问题依旧，然后去脚本仓库找有没有相关的issue，嚯还真有，解决办法是通过brew安装，即<code>brew install libusb</code></p><p> <img src="https://i.loli.net/2020/03/02/YzLmIZRJtuWOHi5.png" alt="No Backend Available"></p><h2 id="鸣谢"><a href="#鸣谢" class="headerlink" title="鸣谢"></a>鸣谢</h2><blockquote><p><a href="https://www.feng.com/post/12857994" target="_blank" rel="noopener">5s降级10.3.3不是很难，就是需要仔细，你就可以完成降级</a><br><a href="https://github.com/MatthewPierson/Vieux" target="_blank" rel="noopener">Vieux - A tool for 32/64 Bit iOS downgrades using OTA Blobs</a><br><a href="https://stackoverflow.com/questions/51055429/why-pip3-install-in-python2-sitepackages" target="_blank" rel="noopener">Why pip3 install in python2 sitepackages</a><br><a href="https://www.nazhuo.work/index.php/archives/11/" target="_blank" rel="noopener">使用 Vieux 将 iphone5s 降级到 10.3.3</a><br><a href="https://zh.ifixit.com/Guide/iPhone+4+-+4S+-+5+-+5S+-+5c+-+6+-+6S+-+%E5%A6%82%E4%BD%95%E5%9C%A8DFU%E6%A8%A1%E5%BC%8F%E5%88%B7%E6%9C%BA%E3%80%82%E5%AF%86%E7%A0%81%E6%81%A2%E5%A4%8D%E3%80%82/28229" target="_blank" rel="noopener">iPhone 4 / 4S / 5 / 5S / 5c / 6 / 6S - 如何在DFU模式刷机。密码恢复。</a></p></blockquote>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h2 id=&quot;序&quot;&gt;&lt;a href=&quot;#序&quot; class=&quot;headerlink&quot; title=&quot;序&quot;&gt;&lt;/a&gt;序&lt;/h2&gt;&lt;p&gt;好像好久都没有更新博客了，还是要养成做记录的习惯。&lt;/p&gt;
&lt;p&gt;偶然看到5s可以降级iOS 10.3.3的帖子，二话不说GKD。中途遇到一些问题在
      
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>入手一台服务器后的一些必备操作</title>
    <link href="http://lougazen.github.io/2019/12/23/%E5%85%A5%E6%89%8B%E4%B8%80%E5%8F%B0%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%90%8E%E7%9A%84%E4%B8%80%E4%BA%9B%E5%BF%85%E5%A4%87%E6%93%8D%E4%BD%9C/"/>
    <id>http://lougazen.github.io/2019/12/23/入手一台服务器后的一些必备操作/</id>
    <published>2019-12-23T08:17:24.000Z</published>
    <updated>2020-03-09T07:31:08.019Z</updated>
    
    <content type="html"><![CDATA[<h2 id="序"><a href="#序" class="headerlink" title="序"></a>序</h2><p>无意中看到腾讯云服务器的<a href="https://cloud.tencent.com/act/campus?fromSource=gwzcw.1293314.1293314.1293314&amp;cps_key=db0b88ca8f49ff0684eddea9ae6bb50b" target="_blank" rel="noopener">活动</a><del>（Pony麻烦结一下广告费谢谢）</del>，趁着现在还不够25岁赶紧续了3次每次最多续1年</p><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="https://i.loli.net/2019/12/23/dAZz8sf3TKNxjkY.png" alt="Pony Ma亏得都要坐公交了" title="">                </div>                <div class="image-caption">Pony Ma亏得都要坐公交了</div>            </figure><h2 id="修改root密码"><a href="#修改root密码" class="headerlink" title="修改root密码"></a>修改root密码</h2><p>拿到服务器第一步就是把默认那个又长又难记的密码改掉</p><p>在命令行执行<code>passwd</code></p><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="https://i.loli.net/2019/12/23/ZJFX53jydVRfSxc.png" alt="passwd" title="">                </div>                <div class="image-caption">passwd</div>            </figure><p>修改成功后记得新开个tab测试新密码能否登陆再退出当前会话</p><h2 id="配置服务器免密登陆ssh-keygen"><a href="#配置服务器免密登陆ssh-keygen" class="headerlink" title="配置服务器免密登陆ssh-keygen"></a>配置服务器免密登陆ssh-keygen</h2><p>先查看本机有没有生成过ssh的公钥和私钥</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> ~/.ssh</span><br><span class="line">ls -al</span><br></pre></td></tr></table></figure><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="https://i.loli.net/2019/12/24/ATaymv9Re6NQ4gB.png" alt="公钥和私钥" title="">                </div>                <div class="image-caption">公钥和私钥</div>            </figure><p>红框中的两个文件分别存放着私钥和公钥，如果没有这两个文件就按以下步骤来</p><p>执行<code>ssh-keygen</code>然后按三下回车</p><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="https://i.loli.net/2019/12/24/BCjFrIUNmEKqw7o.png" alt="ssh-keygen" title="">                </div>                <div class="image-caption">ssh-keygen</div>            </figure><p>现在再去查看就有公钥的信息了</p><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="https://i.loli.net/2019/12/24/Q9Jc2EhPaGAkgbI.png" alt="id_rsa.pub" title="">                </div>                <div class="image-caption">id_rsa.pub</div>            </figure><p>然后把这段公钥上传到目标服务器的<code>~/.ssh/authorized_keys</code>文件当中</p><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="https://i.loli.net/2019/12/24/K64XikdOT1CBmQ5.png" alt="authorized_keys" title="">                </div>                <div class="image-caption">authorized_keys</div>            </figure><p>测试一下，现在可以不用密码顺利登陆进来了</p><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="https://i.loli.net/2019/12/24/W3XUaY7IlskCTiy.png" alt="免密登陆" title="">                </div>                <div class="image-caption">免密登陆</div>            </figure><p>！！！注意：万一电脑丢失记得上服务器把该机器的公钥删掉</p><h2 id="防火墙"><a href="#防火墙" class="headerlink" title="防火墙"></a>防火墙</h2><p>服务器到手的时候自带了firewalld但是并没有启动，使用<code>firewall-cmd --state</code>命令可以查看firewall的运行状态</p><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="https://i.loli.net/2019/12/24/SCoQvKqa1sgHDGJ.png" alt="firewall-cmd --state" title="">                </div>                <div class="image-caption">firewall-cmd --state</div>            </figure><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">systemctl <span class="built_in">enable</span> firewalld <span class="comment"># 启用自动启动</span></span><br><span class="line">systemctl start firewalld <span class="comment"># 启动</span></span><br></pre></td></tr></table></figure><p>成功的话再次查看状态会显示running</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><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">firewall-cmd --permanent --zone=public --add-service=http</span><br><span class="line">firewall-cmd --permanent --zone=public --add-service=https</span><br><span class="line">firewall-cmd --reload</span><br></pre></td></tr></table></figure><h2 id="修改ssh默认端口"><a href="#修改ssh默认端口" class="headerlink" title="修改ssh默认端口"></a>修改ssh默认端口</h2><p><del>稍有常识的人</del> 众所周知ssh默认端口是22，如果不加以修改很容易被人攻击</p><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="https://i.loli.net/2019/12/24/32Xz8Ujdotqrx5F.png" alt="一夜过后被尝试889次登录" title="">                </div>                <div class="image-caption">一夜过后被尝试889次登录</div>            </figure><p>（题外话使用<code>lastb</code>命令可以查看尝试登录的客户端信息，如果信息太多则<code>lastb &gt; fail.log</code>重定向到本地文件再查看）</p><p>ssh端口的配置存放在<code>/etc/ssh/sshd_config</code>中，直接在<code># Port 22</code>下一行添加</p><figure class="highlight shell"><figcaption><span>script</span></figcaption><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">Port 22</span><br><span class="line">Port （你目标的端口）</span><br></pre></td></tr></table></figure><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="https://i.loli.net/2019/12/24/ZbrtGuv4PpnTKcg.png" alt="sshd_config" title="">                </div>                <div class="image-caption">sshd_config</div>            </figure><p>加上22端口是防止现在的连接失效，万一你添加的端口被防火墙屏蔽的那就gg了</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">firewall-cmd --zone=public --add-port=（你目标的端口）/tcp --permanent</span><br><span class="line">firewall-cmd --reload</span><br></pre></td></tr></table></figure><p>重启ssh服务</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">systemctl restart sshd.service</span><br></pre></td></tr></table></figure><p>不要关闭当前连接，新开个tab尝试能否连接成功，成功后再去把22端口删掉</p><p>端口修改后跟ssh相关的命令要带端口参数</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">ssh root@xxx.xx -p 123</span><br><span class="line">sftp -P 123 root@xxx.xx</span><br><span class="line">scp -P 123 ......</span><br></pre></td></tr></table></figure><h2 id="安装docker"><a href="#安装docker" class="headerlink" title="安装docker"></a>安装docker</h2><p>按照官方的<a href="https://docs.docker.com/install/linux/docker-ce/centos/" target="_blank" rel="noopener">文档</a>把下面命令执行一遍就行了</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">sudo yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine</span><br><span class="line">yum install -y yum-utils device-mapper-persistent-data lvm2</span><br><span class="line">yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo</span><br><span class="line">yum install docker-ce docker-ce-cli containerd.io</span><br><span class="line">systemctl <span class="built_in">enable</span> docker</span><br><span class="line">systemctl start docker</span><br></pre></td></tr></table></figure><h2 id="使用docker启动nginx"><a href="#使用docker启动nginx" class="headerlink" title="使用docker启动nginx"></a>使用docker启动nginx</h2><p>首先在srv目录创建文件夹，用于放置ssl证书及nginx配置文件</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">mkdir -p /srv/nginx-data/conf/cert</span><br></pre></td></tr></table></figure><p>把申请到的证书放在<code>/srv/nginx-data/conf/cert</code>目录下</p><p>在<code>/srv/nginx-data/conf</code>目录下创建一个<code>index.conf</code>的文件，内容如下</p><figure class="highlight markdown"><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><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br></pre></td><td class="code"><pre><span class="line"><span class="section"># 使非www域名自动跳转到带www的域名</span></span><br><span class="line">server &#123;</span><br><span class="line"><span class="code">    listen *:80;</span></span><br><span class="line"><span class="code">    listen *:443 ssl http2;</span></span><br><span class="line"><span class="code">    listen [::]:80;</span></span><br><span class="line"><span class="code">    listen [::]:443 ssl http2;</span></span><br><span class="line"><span class="code">    server_name 自己的域名;</span></span><br><span class="line"></span><br><span class="line"><span class="code">    ssl_certificate SSL证书;</span></span><br><span class="line"><span class="code">    ssl_certificate_key SSL证书;</span></span><br><span class="line"><span class="code">    return 301 https://www.自己的域名$request_uri;</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="section"># 使http自动跳转到https</span></span><br><span class="line">server &#123;</span><br><span class="line"><span class="code">    listen *:80;</span></span><br><span class="line"><span class="code">    listen [::]:80;</span></span><br><span class="line"><span class="code">    server_name www.自己的域名;</span></span><br><span class="line"><span class="code">    return 301 https://www.自己的域名$request_uri;</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">server &#123;</span><br><span class="line"><span class="code">    listen *:443 ssl http2;</span></span><br><span class="line"><span class="code">    listen [::]:443 ssl http2;</span></span><br><span class="line"><span class="code">    server_name www.自己的域名;</span></span><br><span class="line"><span class="code">    ssl_certificate SSL证书;</span></span><br><span class="line"><span class="code">    ssl_certificate_key SSL证书;</span></span><br><span class="line"></span><br><span class="line"><span class="code">    #charset koi8-r;</span></span><br><span class="line"><span class="code">    #access_log  /var/log/nginx/host.access.log  main;</span></span><br><span class="line"></span><br><span class="line"><span class="code">    location / &#123;</span></span><br><span class="line"><span class="code">        root   /usr/share/nginx/html;</span></span><br><span class="line"><span class="code">        index  index.html index.htm;</span></span><br><span class="line"><span class="code">    &#125;</span></span><br><span class="line"></span><br><span class="line"><span class="code">    #error_page  404              /404.html;</span></span><br><span class="line"></span><br><span class="line"><span class="code">    # redirect server error pages to the static page /50x.html</span></span><br><span class="line"><span class="code">    #</span></span><br><span class="line"><span class="code">    error_page   500 502 503 504  /50x.html;</span></span><br><span class="line"><span class="code">    location = /50x.html &#123;</span></span><br><span class="line"><span class="code">        root   /usr/share/nginx/html;</span></span><br><span class="line"><span class="code">    &#125;</span></span><br><span class="line"></span><br><span class="line"><span class="code">    # proxy the PHP scripts to Apache listening on 127.0.0.1:80</span></span><br><span class="line"><span class="code">    #</span></span><br><span class="line"><span class="code">    #location ~ \.php$ &#123;</span></span><br><span class="line"><span class="code">    #    proxy_pass   http://127.0.0.1;</span></span><br><span class="line"><span class="code">    #&#125;</span></span><br><span class="line"></span><br><span class="line"><span class="code">    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000</span></span><br><span class="line"><span class="code">    #</span></span><br><span class="line"><span class="code">    #location ~ \.php$ &#123;</span></span><br><span class="line"><span class="code">    #    root           html;</span></span><br><span class="line"><span class="code">    #    fastcgi_pass   127.0.0.1:9000;</span></span><br><span class="line"><span class="code">    #    fastcgi_index  index.php;</span></span><br><span class="line"><span class="code">    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;</span></span><br><span class="line"><span class="code">    #    include        fastcgi_params;</span></span><br><span class="line"><span class="code">    #&#125;</span></span><br><span class="line"></span><br><span class="line"><span class="code">    # deny access to .htaccess files, if Apache's document root</span></span><br><span class="line"><span class="code">    # concurs with nginx's one</span></span><br><span class="line"><span class="code">    #</span></span><br><span class="line"><span class="code">    #location ~ /\.ht &#123;</span></span><br><span class="line"><span class="code">    #    deny  all;</span></span><br><span class="line"><span class="code">    #&#125;</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>完成后执行以下命令启动docker版nginx</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">docker run -d --restart=always --name nginx -v /srv/nginx-data/conf:/etc/nginx/conf.d:ro -p 80:80 -p 443:443 nginx</span><br></pre></td></tr></table></figure><p>其中一些参数的含义如下：</p><ul><li><code>-d</code>代表后台运行</li><li><code>--restart=always</code>代表docker启动的时候该container也一起启动</li><li><code>-name</code>给该容器命名方便管理</li><li><code>-v</code>映射目录，格式<code>host目录:container目录(:ro)</code>，ro代表只读（read-only）</li><li><code>-p</code>开放指定端口，格式<code>host端口:container端口</code></li></ul><p>如果要修改nginx的配置文件，一般都要执行<code>nginx -t</code>测试和<code>nginx -s reload</code>来使生效，而在docker下就要执行</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">docker <span class="built_in">exec</span> nginx /usr/sbin/nginx -t</span><br><span class="line">docker <span class="built_in">exec</span> nginx /usr/sbin/nginx -s reload</span><br></pre></td></tr></table></figure><h2 id="Update-2020-03-09-使用Ghost搭建博客平台"><a href="#Update-2020-03-09-使用Ghost搭建博客平台" class="headerlink" title="Update: 2020-03-09 使用Ghost搭建博客平台"></a>Update: 2020-03-09 使用Ghost搭建博客平台</h2><p>迫于域名备案需要域名能够正常访问并且网站上有相应的备案号信息，就先用Ghost弄个博客平台应付者先。<br>安装的方式还是使用docker，用docker就能很好将各个软件的运行环境隔离开来</p><h3 id="安装Ghost"><a href="#安装Ghost" class="headerlink" title="安装Ghost"></a>安装Ghost</h3><p>直接执行<code>docker run -d --name ghost --restart=always -e url=https://你的域名 ghost</code></p><h3 id="添加nginx配置文件"><a href="#添加nginx配置文件" class="headerlink" title="添加nginx配置文件"></a>添加nginx配置文件</h3><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></pre></td><td class="code"><pre><span class="line"><span class="attribute">location</span> / &#123;</span><br><span class="line">    <span class="attribute">proxy_redirect</span> <span class="literal">off</span>;</span><br><span class="line">    <span class="attribute">proxy_pass</span>   http://172.17.0.5:2368;</span><br><span class="line">    <span class="attribute">proxy_no_cache</span> <span class="number">1</span>;</span><br><span class="line">    <span class="attribute">proxy_http_version</span> <span class="number">1</span>.<span class="number">1</span>;</span><br><span class="line">    <span class="attribute">proxy_set_header</span> X-Real-IP <span class="variable">$remote_addr</span>;</span><br><span class="line">    <span class="attribute">proxy_set_header</span> Host <span class="variable">$host</span>;</span><br><span class="line">    <span class="attribute">proxy_set_header</span> X-Forwarded-For <span class="variable">$proxy_add_x_forwarded_for</span>;</span><br><span class="line">    <span class="attribute">proxy_set_header</span> Upgrade <span class="variable">$http_upgrade</span>;</span><br><span class="line">    <span class="attribute">proxy_set_header</span> Connection <span class="variable">$connection_upgrade</span>;</span><br><span class="line">    <span class="attribute">proxy_set_header</span> X-Forwarded-Proto <span class="variable">$scheme</span>;</span><br><span class="line">    <span class="attribute">client_max_body_size</span> <span class="number">2000m</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>其中两个重点：</p><h4 id="nginx反代的目标ip地址"><a href="#nginx反代的目标ip地址" class="headerlink" title="nginx反代的目标ip地址"></a>nginx反代的目标ip地址</h4><p>因为nginx与ghost是两个不同的环境，docker下的nginx访问宿主机的ip也比较麻烦，万幸在docker同一网络下运行的容器是可以互通的，所以只要拿到ghost的ip地址就行。<br>然鹅事情并没有那么简单，很多容器的运行环境都是十分精简的，精简到ifconfig命令都莫得。好在docker也有命令<code>docker inspect 容器名字/ID</code>去获取这些信息。</p><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="https://i.loli.net/2020/03/08/bMvczCIPpuSWjeJ.png" alt="docker inspect" title="">                </div>                <div class="image-caption">docker inspect</div>            </figure><h4 id="X-Forwarded-Proto"><a href="#X-Forwarded-Proto" class="headerlink" title="X-Forwarded-Proto"></a>X-Forwarded-Proto</h4><p>nginx的配置文件需要带上<code>proxy_set_header X-Forwarded-Proto $scheme;</code>这个header，否则就会出现无限重定向。</p><h3 id="添加footer"><a href="#添加footer" class="headerlink" title="添加footer"></a>添加footer</h3><p>以上这些都弄好后访问域名应该就能顺利打开Ghost了。Ghost的默认管理域名是<code>https://你的域名/ghost</code>，进入后完成一系列初始化设置，在左侧点击Code injection就能添加footer</p><figure class="highlight"><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="tag">&lt;<span class="name">div</span> <span class="attr">style</span>=<span class="string">"padding: 0 0 20px; background:#090a0b; text-align: center;"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">a</span> <span class="attr">href</span>=<span class="string">"http://www.beian.miit.gov.cn"</span> <span class="attr">target</span>=<span class="string">"_blank"</span> <span class="attr">style</span>=<span class="string">"color: hsla(0,0%,100%,.7);"</span>&gt;</span>粤ICP备xx号<span class="tag">&lt;/<span class="name">a</span>&gt;</span></span><br><span class="line">&lt;/&lt;div&gt;</span><br></pre></td></tr></table></figure><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="https://i.loli.net/2020/03/09/lTOZVi7EaXHwJYy.png" alt="footer" title="">                </div>                <div class="image-caption">footer</div>            </figure><h2 id="鸣谢"><a href="#鸣谢" class="headerlink" title="鸣谢"></a>鸣谢</h2><blockquote><p><a href="https://git-scm.com/book/zh/v2/%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8A%E7%9A%84-Git-%E7%94%9F%E6%88%90-SSH-%E5%85%AC%E9%92%A5#r_generate_ssh_key" target="_blank" rel="noopener">4.3 服务器上的 Git - 生成 SSH 公钥</a><br><a href="https://wangchujiang.com/linux-command/c/firewall-cmd.html" target="_blank" rel="noopener">firewall-cmd</a><br><a href="https://www.jianshu.com/p/c18d5347c9b6" target="_blank" rel="noopener">Centos7 修改SSH 端口</a><br><a href="https://docs.docker.com/install/linux/docker-ce/centos/" target="_blank" rel="noopener">Get Docker Engine - Community for CentOS</a><br><a href="https://hub.docker.com/_/ghost/" target="_blank" rel="noopener">ghost - Docker Hub</a><br><a href="https://segmentfault.com/q/1010000014388255" target="_blank" rel="noopener">nginx - 安装在Docker上的Ghost使用环境变量配置了URL后无法访问,“重定向次数过多”</a></p></blockquote>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h2 id=&quot;序&quot;&gt;&lt;a href=&quot;#序&quot; class=&quot;headerlink&quot; title=&quot;序&quot;&gt;&lt;/a&gt;序&lt;/h2&gt;&lt;p&gt;无意中看到腾讯云服务器的&lt;a href=&quot;https://cloud.tencent.com/act/campus?fromSource=gwzcw
      
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>通过brew cask安装指定版本的应用</title>
    <link href="http://lougazen.github.io/2019/12/17/%E9%80%9A%E8%BF%87brew-cask%E5%AE%89%E8%A3%85%E6%8C%87%E5%AE%9A%E7%89%88%E6%9C%AC%E7%9A%84%E5%BA%94%E7%94%A8/"/>
    <id>http://lougazen.github.io/2019/12/17/通过brew-cask安装指定版本的应用/</id>
    <published>2019-12-17T14:58:25.000Z</published>
    <updated>2019-12-23T04:00:43.925Z</updated>
    
    <content type="html"><![CDATA[<h2 id="序"><a href="#序" class="headerlink" title="序"></a>序</h2><p>最近在全新安装DataGrip(2019.3)的时候发现使用以前的洗白工具无法输入序列号，但是从2019.2版本升上来的idea和webstorm却能正常使用。作为一名idea系列的重度使（bai）用（piao）者实在是难受，首先想到的办法就是安装一个旧版本的DataGrip。但是Cask却不像Formulae通过一个@就能指定版本号，需要另辟蹊径。</p><h2 id="准备工作"><a href="#准备工作" class="headerlink" title="准备工作"></a>准备工作</h2><p>先把DataGrip完全卸载<br><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="https://i.loli.net/2019/12/17/cEWU3ZDBgvsYKHt.png" alt="卸载DataGrip" title="">                </div>                <div class="image-caption">卸载DataGrip</div>            </figure></p><p>然后执行一波<code>brew update</code>避免待会配置文件被覆盖</p><h2 id="寻找旧版应用的版本号及sha256信息"><a href="#寻找旧版应用的版本号及sha256信息" class="headerlink" title="寻找旧版应用的版本号及sha256信息"></a>寻找旧版应用的版本号及sha256信息</h2><p>对于大多数开发工具来说官网都会给出旧版的软件版本号或者下载地址等其他信息，如果有sha256值提供就在好不过了，可惜<a href="https://www.jetbrains.com/datagrip/download/other.html" target="_blank" rel="noopener">DataGrip</a>没有给出，只好下载回来自己算sha256</p><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="https://i.loli.net/2019/12/17/QNCOB5ZTRifz3Mu.png" alt="下载目标版本的DataGrip" title="">                </div>                <div class="image-caption">下载目标版本的DataGrip</div>            </figure><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="https://i.loli.net/2019/12/17/gVTJ1B6ewIvcLus.png" alt="计算哈希" title="">                </div>                <div class="image-caption">计算哈希</div>            </figure><h2 id="替换目标软件的Cask下载源地址"><a href="#替换目标软件的Cask下载源地址" class="headerlink" title="替换目标软件的Cask下载源地址"></a>替换目标软件的Cask下载源地址</h2><p>执行<code>brew cask edit datagrip</code>就会在默认编辑器打开这个软件的配置文件</p><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="https://i.loli.net/2019/12/17/UnozwtJDTMFXYh9.png" alt="brew cask edit datagrip" title="">                </div>                <div class="image-caption">brew cask edit datagrip</div>            </figure><p>我们主要改的是红框中的两个信息，把它替换成指定版本的应用信息，保存退出</p><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="https://i.loli.net/2019/12/17/r569XZWOVjmcEwo.png" alt="修改版本号和哈希" title="">                </div>                <div class="image-caption">修改版本号和哈希</div>            </figure><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="https://i.loli.net/2019/12/17/tLVYFqg8nT2bKGz.png" alt="修改版本号和哈希" title="">                </div>                <div class="image-caption">修改版本号和哈希</div>            </figure><p>很明显这个配置文件所在的目录是个git仓库，所以改错了不用怕，到时候一波<code>git reset --hard</code>即可复原</p><h2 id="执行安装命令"><a href="#执行安装命令" class="headerlink" title="执行安装命令"></a>执行安装命令</h2><p>这个时候执行<code>brew cask install datagrip</code>，顺利的话就会自动下载旧版本并且顺利安装</p><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="https://i.loli.net/2019/12/17/oaHz1MYjsRQ9wp6.png" alt="brew cask install datagrip" title="">                </div>                <div class="image-caption">brew cask install datagrip</div>            </figure><h2 id="鸣谢"><a href="#鸣谢" class="headerlink" title="鸣谢"></a>鸣谢</h2><blockquote><p><a href="https://zeckli.github.io/en/2016/11/05/use-homebrew-cask-to-downgrad-or-install-en.html" target="_blank" rel="noopener">Use Homebrew Cask to downgrade or install specific version of package</a></p></blockquote>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h2 id=&quot;序&quot;&gt;&lt;a href=&quot;#序&quot; class=&quot;headerlink&quot; title=&quot;序&quot;&gt;&lt;/a&gt;序&lt;/h2&gt;&lt;p&gt;最近在全新安装DataGrip(2019.3)的时候发现使用以前的洗白工具无法输入序列号，但是从2019.2版本升上来的idea和webstorm却
      
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>打造Mac下舒适的终端</title>
    <link href="http://lougazen.github.io/2019/12/12/%E6%89%93%E9%80%A0Mac%E4%B8%8B%E8%88%92%E9%80%82%E7%9A%84%E7%BB%88%E7%AB%AF/"/>
    <id>http://lougazen.github.io/2019/12/12/打造Mac下舒适的终端/</id>
    <published>2019-12-12T15:54:46.000Z</published>
    <updated>2019-12-23T04:00:43.924Z</updated>
    
    <content type="html"><![CDATA[<h2 id="序"><a href="#序" class="headerlink" title="序"></a>序</h2><p>拖延症拖了一年终于要开始打造自己的博客了<em>(´ཀ`」 ∠)</em>，先拿最近捣鼓的zsh开刀吧</p><h2 id="准备"><a href="#准备" class="headerlink" title="准备"></a>准备</h2><p><a href="https://brew.sh/index_zh-cn" target="_blank" rel="noopener">brew</a>、iTerm2和<a href="https://ohmyz.sh/" target="_blank" rel="noopener">Oh-My-Zsh</a></p><p>使用brew安装nerd-font字体</p><figure class="highlight shell"><figcaption><span>script</span></figcaption><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">brew tap caskroom/fonts</span><br><span class="line">brew cask install font-hack-nerd-font</span><br></pre></td></tr></table></figure><p>配置iTerm2针对非ASCII码字符的字体</p><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="https://i.loli.net/2019/12/16/moWqMef9wHILBYU.png" alt="配置iTerm2针对非ASCII码字符的字体" title="">                </div>                <div class="image-caption">配置iTerm2针对非ASCII码字符的字体</div>            </figure><h2 id="配置zsh主题"><a href="#配置zsh主题" class="headerlink" title="配置zsh主题"></a>配置zsh主题</h2><p>zsh的配置文件存放在<code>~/.zshrc</code>下，看到</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ZSH_THEME="robbyrussell"</span><br></pre></td></tr></table></figure><p>这一行，这里就是配置主题的地方，默认自带一堆主题放在<code>~/.oh-my-zsh/theme</code>目录下，也可以上<a href="https://github.com/ohmyzsh/ohmyzsh/wiki/Themes" target="_blank" rel="noopener">github</a>上查看各个主题的效果</p><p>当然个人感觉最叼的还是这个<a href="https://github.com/Powerlevel9k/powerlevel9k" target="_blank" rel="noopener">powerlevel9k</a>主题</p><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="https://i.loli.net/2019/12/16/NUrfXGsnjuo8Zxv.gif" alt="powerlevel9k主题" title="">                </div>                <div class="image-caption">powerlevel9k主题</div>            </figure><p>首先把主题安装到本地</p><figure class="highlight shell"><figcaption><span>script</span></figcaption><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/bhilburn/powerlevel9k.git ~/.oh-my-zsh/custom/themes/powerlevel9k</span><br></pre></td></tr></table></figure><p>修改<code>~/.zshrc</code>的主题配置</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ZSH_THEME="powerlevel9k/powerlevel9k"</span><br></pre></td></tr></table></figure><p>重新加载zsh使配置生效</p><figure class="highlight shell"><figcaption><span>script</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">source ~/.zshrc</span><br></pre></td></tr></table></figure><p>然后提示就变样了（先忽略苹果logo的信息，后面会提到）</p><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="https://i.loli.net/2019/12/16/pCnDS4baKfAdetZ.png" alt="安装powerlevel9k" title="">                </div>                <div class="image-caption">安装powerlevel9k</div>            </figure><p>根据自己的喜好配置一下（注意需要加在ZSH_THEME的前面，不然前面说的nerd-font字体会加载不出来），详细可进入p9k的github阅读原文档</p><figure class="highlight markdown"><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">POWERLEVEL9K_MODE="nerdfont-complete"</span><br><span class="line">POWERLEVEL9K<span class="emphasis">_LEFT_</span>PROMPT<span class="emphasis">_ELEMENTS=(os_</span>icon root<span class="emphasis">_indicator context ssh dir_</span>writable dir vcs status)</span><br><span class="line">POWERLEVEL9K<span class="emphasis">_RIGHT_</span>PROMPT_ELEMENTS=()</span><br><span class="line">POWERLEVEL9K<span class="emphasis">_PROMPT_</span>ADD_NEWLINE=true</span><br></pre></td></tr></table></figure><ul><li><code>POWERLEVEL9K_MODE</code>：设置 powerlevel9k 的字体是我们前面下载的</li><li><code>POWERLEVEL9K_LEFT_PROMPT_ELEMENTS</code>：将前面居右的几个元素放在左边了</li><li><code>POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS</code>：右边不放置任何元素（如果你喜欢在右边也可以加）</li><li><code>POWERLEVEL9K_PROMPT_ADD_NEWLINE</code>：在每个提示之前添加换行符</li></ul><p>修改完的效果应该是这样子的</p><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="https://i.loli.net/2019/12/16/6xi9PybSLRKcJz3.png" alt="配置powerlevel9k" title="">                </div>                <div class="image-caption">配置powerlevel9k</div>            </figure><h2 id="配置iTerm2配色"><a href="#配置iTerm2配色" class="headerlink" title="配置iTerm2配色"></a>配置iTerm2配色</h2><p>iTerm2默认黑色还是太丑了，上<a href="https://github.com/mbadolato/iTerm2-Color-Schemes" target="_blank" rel="noopener">这里</a>挑了个Ubuntu主题</p><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="https://i.loli.net/2019/12/16/CynTDgk7PRGXh8f.png" alt="iTerm2配色" title="">                </div>                <div class="image-caption">iTerm2配色</div>            </figure><p>啊舒服了٩(๑´0`๑)۶</p><h2 id="安装zsh插件"><a href="#安装zsh插件" class="headerlink" title="安装zsh插件"></a>安装zsh插件</h2><p>以上那些都是过眼隐的，真正让使用者感到舒服的地方来了</p><p>先列一下我的插件列表</p><ul><li>git</li><li>zsh-syntax-highlighting</li><li>zsh-autosuggestions</li><li>command-not-found</li><li>zsh_reload</li><li>git-open</li><li>z</li><li>safe-paste</li><li>sudo</li><li>extract</li></ul><h3 id="git"><a href="#git" class="headerlink" title="git"></a>git</h3><p>默认自带，不说</p><h3 id="zsh-syntax-highlighting"><a href="#zsh-syntax-highlighting" class="headerlink" title="zsh-syntax-highlighting"></a>zsh-syntax-highlighting</h3><p>用于显示你当前输入的命令是否正确</p><figure class="highlight shell"><figcaption><span>script</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">brew install zsh-syntax-highlighting</span><br></pre></td></tr></table></figure><p>正常来讲可以直接把<code>zsh-syntax-highlighting</code>加到配置文件中即可启用，如果出现<code>plugin not found</code>的情况则改用如下方式进行配置</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">source /usr/local/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh</span><br></pre></td></tr></table></figure><h3 id="zsh-autosuggestions"><a href="#zsh-autosuggestions" class="headerlink" title="zsh-autosuggestions"></a>zsh-autosuggestions</h3><p>历史记录提示，按➡️方向键自动补全</p><figure class="highlight shell"><figcaption><span>script</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">brew install zsh-autosuggestions</span><br></pre></td></tr></table></figure><p>跟上一个配置同理，如果出现<code>plugin not found</code>的情况则改用如下方式进行配置</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">source /usr/local/share/zsh-autosuggestions/zsh-autosuggestions.zsh</span><br></pre></td></tr></table></figure><h3 id="command-not-found"><a href="#command-not-found" class="headerlink" title="command-not-found"></a>command-not-found</h3><p>对于command not found的结果会提示一个相似的命令（多出现于拼写错误）</p><h3 id="zsh-reload"><a href="#zsh-reload" class="headerlink" title="zsh_reload"></a>zsh_reload</h3><p>直接执行<code>src</code>即可完成<code>source ~/.zshrc</code>操作</p><h3 id="git-open"><a href="#git-open" class="headerlink" title="git-open"></a>git-open</h3><p>在终端里打开当前项目的远程仓库地址</p><figure class="highlight shell"><figcaption><span>script</span></figcaption><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/paulirish/git-open.git $ZSH_CUSTOM/plugins/git-open</span><br></pre></td></tr></table></figure><h3 id="z"><a href="#z" class="headerlink" title="z"></a>z</h3><p>zsh自带的autojump</p><h3 id="safe-paste"><a href="#safe-paste" class="headerlink" title="safe-paste"></a>safe-paste</h3><p>顾名思义，对于有换行符的内容不会立马执行</p><h3 id="sudo"><a href="#sudo" class="headerlink" title="sudo"></a>sudo</h3><p>双击 Esc，zsh 会把上一条命令加上 sudo 给你</p><h3 id="extract"><a href="#extract" class="headerlink" title="extract"></a>extract</h3><p>万能解压命令</p><h2 id="其他非zsh的插件"><a href="#其他非zsh的插件" class="headerlink" title="其他非zsh的插件"></a>其他非zsh的插件</h2><h3 id="colorls"><a href="#colorls" class="headerlink" title="colorls"></a>colorls</h3><p>列出文件时带图标</p><figure class="highlight shell"><figcaption><span>script</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">gem install colorls</span><br></pre></td></tr></table></figure><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="https://i.loli.net/2019/12/16/qrk1oOXgwPUsd4p.png" alt="colorls" title="">                </div>                <div class="image-caption">colorls</div>            </figure><p>然后加个alias到配置文件</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">alias cll='colorls -l --gs'</span><br></pre></td></tr></table></figure><p>以后输入<code>cll</code>即可</p><h3 id="archey"><a href="#archey" class="headerlink" title="archey"></a>archey</h3><p>显示系统信息</p><figure class="highlight shell"><figcaption><span>script</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">brew install archey</span><br></pre></td></tr></table></figure><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="https://i.loli.net/2019/12/16/85scRPWveNCi4kM.png" alt="archey" title="">                </div>                <div class="image-caption">archey</div>            </figure><p>然后把<code>archey</code>这个命令加到配置文件即可每次打开都显示系统信息</p><p>顺带提一下archey那种图案的生成方式，有两个小工具可以做到，一个是figlet，另一个是toilet</p><figure class="highlight shell"><figcaption><span>script</span></figcaption><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">brew install figlet</span><br><span class="line">brew install toilet</span><br></pre></td></tr></table></figure><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="https://i.loli.net/2019/12/16/gwlevVHQUCZAFr6.png" alt="figlet与toilet" title="">                </div>                <div class="image-caption">figlet与toilet</div>            </figure><h2 id="后记（挖坑）"><a href="#后记（挖坑）" class="headerlink" title="后记（挖坑）"></a><del>后记（挖坑）</del></h2><p><del>这一套下来在iTerm下面使用简直是强无敌，但是考虑还有系统自带的终端及idea和vscode的终端都要配置一遍是在是烦躁，在寻找有没有办法针对不同的shell加载不同的配置文件</del></p><h2 id="（2019-12-22填坑）针对不同终端使用不同的主题"><a href="#（2019-12-22填坑）针对不同终端使用不同的主题" class="headerlink" title="（2019-12-22填坑）针对不同终端使用不同的主题"></a>（2019-12-22填坑）针对不同终端使用不同的主题</h2><p>通过查看<a href="https://github.com/obihann/archey-osx/blob/master/bin/archey" target="_blank" rel="noopener">archey</a>发现，终端软件（不是shell）的信息存放在<code>${TERM_PROGRAM}</code>这个变量里，遂修把配置文件中<code>ZSH_THEME=&quot;powerlevel9k/powerlevel9k&quot;</code>这一行改为</p><figure class="highlight markdown"><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></pre></td><td class="code"><pre><span class="line">if [ "$&#123;TERM_PROGRAM&#125;" = "iTerm.app" ]; then</span><br><span class="line"><span class="code">    POWERLEVEL9K_MODE="nerdfont-complete"</span></span><br><span class="line"><span class="code">    POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(os_icon root_indicator context ssh dir_writable dir vcs status)</span></span><br><span class="line"><span class="code">    POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=()</span></span><br><span class="line"><span class="code">    POWERLEVEL9K_PROMPT_ADD_NEWLINE=true</span></span><br><span class="line"><span class="code">    ZSH_THEME="powerlevel9k/powerlevel9k"</span></span><br><span class="line">else</span><br><span class="line"><span class="code">    ZSH_THEME="ys"</span></span><br><span class="line">fi</span><br></pre></td></tr></table></figure><p>（顺便把powerlevel9k的一些配置也放到了一起）</p><p>最终效果</p><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="https://i.loli.net/2019/12/22/6pcKn2rWsANwaMf.png" alt="自带Terminal和vscode" title="">                </div>                <div class="image-caption">自带Terminal和vscode</div>            </figure><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="https://i.loli.net/2019/12/22/euFiva8HWTqzMk1.png" alt="iTerm" title="">                </div>                <div class="image-caption">iTerm</div>            </figure><p>完美<br><figure class="image-bubble">                <div class="img-lightbox">                    <div class="overlay"></div>                    <img src="https://i.loli.net/2019/12/22/XiYMjbp7cIRslaE.gif" alt="👏" title="">                </div>                <div class="image-caption">👏</div>            </figure></p><h2 id="鸣谢"><a href="#鸣谢" class="headerlink" title="鸣谢"></a>鸣谢</h2><blockquote><p><a href="https://blog.biezhi.me/2018/11/build-a-beautiful-mac-terminal-environment.html" target="_blank" rel="noopener">打造 Mac 下高颜值好用的终端环境</a><br><a href="https://github.com/ohmyzsh/ohmyzsh" target="_blank" rel="noopener">oh-my-zsh</a><br><a href="https://github.com/Powerlevel9k/powerlevel9k" target="_blank" rel="noopener">powerlevel9k</a><br><a href="https://github.com/mbadolato/iTerm2-Color-Schemes" target="_blank" rel="noopener">iTerm2-Color-Schemes</a></p></blockquote>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h2 id=&quot;序&quot;&gt;&lt;a href=&quot;#序&quot; class=&quot;headerlink&quot; title=&quot;序&quot;&gt;&lt;/a&gt;序&lt;/h2&gt;&lt;p&gt;拖延症拖了一年终于要开始打造自己的博客了&lt;em&gt;(´ཀ`」 ∠)&lt;/em&gt;，先拿最近捣鼓的zsh开刀吧&lt;/p&gt;
&lt;h2 id=&quot;准备&quot;&gt;&lt;a hre
      
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>Hello World</title>
    <link href="http://lougazen.github.io/2018/12/05/hello-world/"/>
    <id>http://lougazen.github.io/2018/12/05/hello-world/</id>
    <published>2018-12-05T14:21:31.000Z</published>
    <updated>2019-12-23T09:40:32.322Z</updated>
    
    <content type="html"><![CDATA[<p>Welcome to <a href="https://hexo.io/" target="_blank" rel="noopener">Hexo</a>! This is your very first post. Check <a href="https://hexo.io/docs/" target="_blank" rel="noopener">documentation</a> for more info. If you get any problems when using Hexo, you can find the answer in <a href="https://hexo.io/docs/troubleshooting.html" target="_blank" rel="noopener">troubleshooting</a> or you can ask me on <a href="https://github.com/hexojs/hexo/issues" target="_blank" rel="noopener">GitHub</a>.</p><h2 id="Quick-Start"><a href="#Quick-Start" class="headerlink" title="Quick Start"></a>Quick Start</h2><h3 id="Create-a-new-post"><a href="#Create-a-new-post" class="headerlink" title="Create a new post"></a>Create a new post</h3><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">hexo new <span class="string">"My New Post"</span></span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/writing.html" target="_blank" rel="noopener">Writing</a></p><h3 id="Run-server"><a href="#Run-server" class="headerlink" title="Run server"></a>Run server</h3><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">hexo server</span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/server.html" target="_blank" rel="noopener">Server</a></p><h3 id="Generate-static-files"><a href="#Generate-static-files" class="headerlink" title="Generate static files"></a>Generate static files</h3><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">hexo generate</span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/generating.html" target="_blank" rel="noopener">Generating</a></p><h3 id="Deploy-to-remote-sites"><a href="#Deploy-to-remote-sites" class="headerlink" title="Deploy to remote sites"></a>Deploy to remote sites</h3><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">hexo deploy</span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/deployment.html" target="_blank" rel="noopener">Deployment</a></p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;p&gt;Welcome to &lt;a href=&quot;https://hexo.io/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Hexo&lt;/a&gt;! This is your very first post. Check &lt;a href=&quot;https://hexo.
      
    
    </summary>
    
    
  </entry>
  
</feed>
