<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>2021 on Ricky</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/</link><description>Recent content in 2021 on Ricky</description><generator>Hugo -- gohugo.io</generator><language>zh-tw</language><lastBuildDate>Mon, 27 Dec 2021 15:47:12 +0800</lastBuildDate><atom:link href="https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/index.xml" rel="self" type="application/rss+xml"/><item><title>Nginx怎样隐藏上游错误</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211227-how-nginx-hide-upstream-errors/</link><pubDate>Mon, 27 Dec 2021 15:47:12 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211227-how-nginx-hide-upstream-errors/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://russelltao.github.io/2021/02/22/nginx/Nginx%E6%80%8E%E6%A0%B7%E9%9A%90%E8%97%8F%E4%B8%8A%E6%B8%B8%E9%94%99%E8%AF%AF/#more" target="_blank" rel="noopener">Nginx 怎样隐藏上游错误&lt;/a>&lt;/li>
&lt;/ul>
&lt;h5 id="nginx-允许对以下-7-种可以进行重试的错误码启用-next-upstream-功能">Nginx 允许对以下 7 种可以进行重试的错误码启用 next upstream 功能&lt;/h5>
&lt;ul>
&lt;li>403 Forbidden&lt;/li>
&lt;li>404 Not Found&lt;/li>
&lt;li>429 Too Many Requests&lt;/li>
&lt;li>500 Internal Server Error&lt;/li>
&lt;li>502 Bad Gateway&lt;/li>
&lt;li>503 Server Unavailable&lt;/li>
&lt;li>504 Gateway Timeout&lt;/li>
&lt;/ul>
&lt;h5 id="当上游返回-404-错误时改为通过-200-返回一张找不到资源的图片">当上游返回 404 错误时，改为通过 200 返回一张找不到资源的图片&lt;/h5>
&lt;blockquote>
&lt;p>此时，可以通过 &lt;code>proxy_intercept_errors&lt;/code> 指令完成这一功能
当 &lt;code>proxy_intercept_errors&lt;/code> 开启后，对于上游返回的大于等于 300 响应码的请求，都可以基于 error_page 指令继续处理&lt;/p>&lt;/blockquote>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-nginx" data-lang="nginx">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">location&lt;/span> &lt;span style="color:#e6db74">/ih&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">proxy_pass&lt;/span> &lt;span style="color:#e6db74">http://ihBackend&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">proxy_intercept_errors&lt;/span> &lt;span style="color:#66d9ef">on&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">error_page&lt;/span> &lt;span style="color:#ae81ff">404&lt;/span> = &lt;span style="color:#e6db74">/404.html&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">location&lt;/span> = &lt;span style="color:#e6db74">/404.html&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">alias&lt;/span> &lt;span style="color:#e6db74">html/404_not_found.html&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Argo CD ApplicationSet Controller: 世界為我而轉動！</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211227-argo-cd-applicationset-controller/</link><pubDate>Mon, 27 Dec 2021 09:41:03 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211227-argo-cd-applicationset-controller/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://medium.com/starbugs/argo-cd-applicationset-controller-%E4%B8%96%E7%95%8C%E7%82%BA%E6%88%91%E8%80%8C%E8%BD%89%E5%8B%95-a837f9392298" target="_blank" rel="noopener">Argo CD ApplicationSet Controller: 世界為我而轉動！&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://github.com/argoproj/argo-cd" target="_blank" rel="noopener">Argo CD&lt;/a>&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 安裝 kind，其他平台安裝方式請參閱官方文件&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 用來運行輕量 K8s Cluster 於本地端&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>~$ brew install kind
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 安裝 kubectx，其他平台安裝方式請參閱官方文件&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 用來方便切換不同 k8s context&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>~$ brew install kubectx
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 安裝 helm，其他平台安裝方式請參閱官方文件&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># K8s 套件管理工具&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>~$ brew install helm
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 安裝 kubectl, 其他平台安裝方式請參閱官方文件&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 用來與 K8s Cluster API Server 溝通&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>~$ brew install kubectl
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 安裝 argocd cli, 其他平台安裝方式請參閱官方文件&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 用來與 Argo CD 溝通&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>~$ brew install argocd
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>golang的AES加密和解密的三种模式实现（CBC/ECB/CFB)</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211222-aes-encryption-and-decryption-three-modes-implementation/</link><pubDate>Wed, 22 Dec 2021 17:40:52 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211222-aes-encryption-and-decryption-three-modes-implementation/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://blog.csdn.net/mirage003/article/details/87868999" target="_blank" rel="noopener">golang 的 AES 加密和解密的三种模式实现（CBC/ECB/CFB)&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://levelup.gitconnected.com/a-short-guide-to-encryption-using-go-da97c928259f" target="_blank" rel="noopener">How to encrypt a file using Go&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>【理解 Cilium 系列文章】(一) 初識 Cilium</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211221-understanding-cilium/</link><pubDate>Tue, 21 Dec 2021 13:04:38 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211221-understanding-cilium/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://www.gushiciku.cn/pl/geTr/zh-hk" target="_blank" rel="noopener">【理解 Cilium 系列文章】(一) 初識 Cilium&lt;/a>&lt;/li>
&lt;/ul>
&lt;h4 id="當前-k8s-service-負載均衡的實現現狀">當前 k8s Service 負載均衡的實現現狀&lt;/h4>
&lt;p>在 Cilium 出現之前， Service 由 kube-proxy 來實現，實現方式有 userspace ， iptables ， ipvs 三種模式。&lt;/p>
&lt;h5 id="userspace">Userspace&lt;/h5>
&lt;p>當前模式下，kube-proxy 作為反向代理,監聽隨機端口，通過 iptables 規則將流量重定向到代理端口，再由 kube-proxy 將流量轉發到 後端 pod。Service 的請求會先從用户空間進入內核 iptables，然後再回到用户空間，代價較大，性能較差。&lt;/p>
&lt;h5 id="iptables">Iptables&lt;/h5>
&lt;p>存在的問題：&lt;/p>
&lt;p>1.可擴展性差。隨着 service 數據達到數千個，其控制面和數據面的性能都會急劇下降。原因在於 iptables 控制面的接口設計中，每添加一條規則，需要遍歷和修改所有的規則，其控制面性能是 O(n²) 。在數據面，規則是用鏈表組織的，其性能是 O(n)&lt;/p>
&lt;p>2.LB 調度算法僅支持隨機轉發&lt;/p>
&lt;h5 id="ipvs-模式">Ipvs 模式&lt;/h5>
&lt;p>IPVS 是專門為 LB 設計的。它用 hash table 管理 service，對 service 的增刪查找都是 O(1)的時間複雜度。不過 IPVS 內核模塊沒有 SNAT 功能，因此借用了 iptables 的 SNAT 功能。&lt;/p>
&lt;p>IPVS 針對報文做 DNAT 後，將連接信息保存在 nf_conntrack 中，iptables 據此接力做 SNAT。該模式是目前 Kubernetes 網絡性能最好的選擇。但是由於 nf_conntrack 的複雜性，帶來了很大的性能損耗。騰訊針對該問題做過相應的優化 【繞過 conntrack，使用 eBPF 增強 IPVS 優化 K8s 網絡性能】&lt;/p></description></item><item><title>不使用 kube-proxy 的 Kubernetes</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211220-kubeproxy-free/</link><pubDate>Mon, 20 Dec 2021 17:57:13 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211220-kubeproxy-free/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://docs.cilium.io/en/v1.9/gettingstarted/kubeproxy-free/" target="_blank" rel="noopener">不使用 kube-proxy 的 Kubernetes&lt;/a>&lt;/li>
&lt;/ul>
&lt;h4 id="快速開始">快速開始&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>kubeadm init --skip-phases&lt;span style="color:#f92672">=&lt;/span>addon/kube-proxy
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 設定 Helm 倉庫&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>helm repo add cilium https://helm.cilium.io/
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>helm install cilium cilium/cilium --version 1.9.18 &lt;span style="color:#ae81ff">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ae81ff">&lt;/span> --namespace kube-system &lt;span style="color:#ae81ff">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ae81ff">&lt;/span> --set kubeProxyReplacement&lt;span style="color:#f92672">=&lt;/span>strict &lt;span style="color:#ae81ff">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ae81ff">&lt;/span> --set k8sServiceHost&lt;span style="color:#f92672">=&lt;/span>REPLACE_WITH_API_SERVER_IP &lt;span style="color:#ae81ff">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ae81ff">&lt;/span> --set k8sServicePort&lt;span style="color:#f92672">=&lt;/span>REPLACE_WITH_API_SERVER_PORT
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Zsh tab 補完無法使用</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211210-zsh-tab-completion-not-working/</link><pubDate>Fri, 10 Dec 2021 17:44:49 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211210-zsh-tab-completion-not-working/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://stackoverflow.com/questions/46939906/zsh-tab-completion-not-working" target="_blank" rel="noopener">Zsh tab 補完無法使用&lt;/a>&lt;/li>
&lt;/ul>
&lt;h4 id="問題">問題&lt;/h4>
&lt;p>雖然我之前用過 Oh-My-Zsh，但這次（設定新電腦）我決定盡量不要安裝它，讓環境更精簡。現在我想單獨取用 Oh-My-Zsh 的大小寫不敏感補完功能。翻查原始碼後，我找到下面這行：
&lt;code>zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' 'r:|=*' 'l:|=* r:|=*'&lt;/code>&lt;/p>
&lt;p>我相當確定 Oh-My-Zsh 就是用這行達成我的需求，所以我把它加進 &lt;code>.zshrc&lt;/code>。重啟終端機後輸入 &lt;code>cd desk&lt;/code>，再按 [tab]，結果沒有作用，並沒有補完成 &lt;code>cd Desktop/&lt;/code>。&lt;/p>
&lt;p>以下是完整的 &lt;code>.zshrc&lt;/code> 供參考：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Source - https://stackoverflow.com/q&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Posted by kylemart&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Retrieved 2026-01-05, License - CC BY-SA 3.0&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># pure shell theme&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>autoload -U promptinit; promptinit
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>prompt pure
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># completion definitions&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>zstyle &lt;span style="color:#e6db74">&amp;#39;:completion:*&amp;#39;&lt;/span> matcher-list &lt;span style="color:#e6db74">&amp;#39;m:{a-zA-Z}={A-Za-z}&amp;#39;&lt;/span> &lt;span style="color:#e6db74">&amp;#39;r:|=*&amp;#39;&lt;/span> &lt;span style="color:#e6db74">&amp;#39;l:|=* r:|=*&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>fpath&lt;span style="color:#f92672">=(&lt;/span>/usr/local/share/zsh-completions $fpath&lt;span style="color:#f92672">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># syntax highlighting (must be last line)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>source /usr/local/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="答案">答案&lt;/h4>
&lt;p>只要 &lt;code>autoload&lt;/code> 並執行 &lt;code>compinit&lt;/code> 即可。&lt;/p></description></item><item><title>Linkerd 2.8 - 實現超級簡單又安全的多叢集(multicluster) Kubernetes 架構</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211209-linkerd-multi-kubernetes-cluster-feature-overview/</link><pubDate>Thu, 09 Dec 2021 09:25:44 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211209-linkerd-multi-kubernetes-cluster-feature-overview/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://rammusxu.github.io/2020/07/28/Linkerd-Multi-Kubernetes-Cluster-Feature-Overview/" target="_blank" rel="noopener">Linkerd 2.8 - 實現超級簡單又安全的多叢集(multicluster) Kubernetes 架構&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>撰寫 Bash 腳本的最佳實務</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211206-bash-best-practices/</link><pubDate>Mon, 06 Dec 2021 11:11:54 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211206-bash-best-practices/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://kvz.io/bash-best-practices.html" target="_blank" rel="noopener">撰寫 Bash 腳本的最佳實務&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.javacodegeeks.com/2013/10/shell-scripting-best-practices.html" target="_blank" rel="noopener">Shell 腳本撰寫最佳實務&lt;/a>&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#!/usr/bin/env bash
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#75715e"># Bash3 Boilerplate. Copyright (c) 2014, kvz.io&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>set -o errexit
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>set -o pipefail
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>set -o nounset
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># set -o xtrace&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Set magic variables for current file &amp;amp; dir&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>__dir&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#66d9ef">$(&lt;/span>cd &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#66d9ef">$(&lt;/span>dirname &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>BASH_SOURCE[0]&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#66d9ef">)&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span> &lt;span style="color:#f92672">&amp;amp;&amp;amp;&lt;/span> pwd&lt;span style="color:#66d9ef">)&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>__file&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>__dir&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">/&lt;/span>&lt;span style="color:#66d9ef">$(&lt;/span>basename &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>BASH_SOURCE[0]&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#66d9ef">)&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>__base&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#66d9ef">$(&lt;/span>basename &lt;span style="color:#e6db74">${&lt;/span>__file&lt;span style="color:#e6db74">}&lt;/span> .sh&lt;span style="color:#66d9ef">)&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>__root&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#66d9ef">$(&lt;/span>cd &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#66d9ef">$(&lt;/span>dirname &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>__dir&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#66d9ef">)&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span> &lt;span style="color:#f92672">&amp;amp;&amp;amp;&lt;/span> pwd&lt;span style="color:#66d9ef">)&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span> &lt;span style="color:#75715e"># &amp;lt;-- change this as it depends on your app&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>arg1&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>1&lt;span style="color:#66d9ef">:-&lt;/span>&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h5 id="使用-shift-讀取函式參數">使用 shift 讀取函式參數&lt;/h5>
&lt;blockquote>
&lt;p>這樣在日後需要調整參數順序時會更容易。&lt;/p>&lt;/blockquote>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Processes a file.&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># $1 - the name of the input file&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># $2 - the name of the output file&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>process_file&lt;span style="color:#f92672">(){&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> local -r input_file&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>$1&lt;span style="color:#e6db74">&amp;#34;&lt;/span>; shift
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> local -r output_file&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>$1&lt;span style="color:#e6db74">&amp;#34;&lt;/span>; shift
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h5 id="宣告你的變數">宣告你的變數&lt;/h5>
&lt;blockquote>
&lt;p>若可攜性是重點，請用 &lt;code>typeset&lt;/code> 取代 &lt;code>declare&lt;/code>。&lt;/p></description></item><item><title>Day 28 - Kubernetes 第三方好用工具介紹</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211202-10252675/</link><pubDate>Thu, 02 Dec 2021 13:28:09 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211202-10252675/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://ithelp.ithome.com.tw/articles/10252675" target="_blank" rel="noopener">Day 28 - Kubernetes 第三方好用工具介紹&lt;/a>&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>$ kubectl get pods
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>NAME READY STATUS RESTARTS AGE
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>ithome-6564f65698-947rv 1/1 Running &lt;span style="color:#ae81ff">0&lt;/span> 84s
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>ithome-6564f65698-fglr9 1/1 Running &lt;span style="color:#ae81ff">0&lt;/span> 84s
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>ithome-6564f65698-k5wtg 1/1 Running &lt;span style="color:#ae81ff">0&lt;/span> 84s
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>ithome-6564f65698-rrvk4 1/1 Running &lt;span style="color:#ae81ff">0&lt;/span> 84s
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>ithome-6564f65698-zhwlj 1/1 Running &lt;span style="color:#ae81ff">0&lt;/span> 84s
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="sternkail">&lt;a href="https://github.com/wercker/stern" target="_blank" rel="noopener">Stern&lt;/a>/Kail&lt;/h4>
&lt;blockquote>
&lt;p>創建出來的 Pod 名稱上面都會有一些不好閱讀的亂數&lt;/p>
&lt;p>如果使用 kubectl 來觀察個別 Pod 的 log 就必須要於不同的 pod 之間來回切換&lt;/p>
&lt;p>這方面的工具滿多的，譬如 Stern, Kube-tail, Kail 等都可以&lt;/p>&lt;/blockquote>
&lt;p>上述範例會有五個 pod，而且這五個 pod 的名稱都是 ithome 開頭，因此我可以直接用 &lt;code>stern ithom&lt;/code> 的方式來抓取這些 pod 的資訊，結果如下圖&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>$ stern ithome
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>...
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>ithome-6564f65698-zhwlj netutils Hello! &lt;span style="color:#ae81ff">369&lt;/span> secs elapsed...
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>ithome-6564f65698-fglr9 netutils Hello! &lt;span style="color:#ae81ff">369&lt;/span> secs elapsed...
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>ithome-6564f65698-947rv netutils Hello! &lt;span style="color:#ae81ff">367&lt;/span> secs elapsed...
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>ithome-6564f65698-k5wtg netutils Hello! &lt;span style="color:#ae81ff">368&lt;/span> secs elapsed...
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>ithome-6564f65698-rrvk4 netutils Hello! &lt;span style="color:#ae81ff">369&lt;/span> secs elapsed...
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>ithome-6564f65698-zhwlj netutils Hello! &lt;span style="color:#ae81ff">370&lt;/span> secs elapsed...
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>ithome-6564f65698-fglr9 netutils Hello! &lt;span style="color:#ae81ff">370&lt;/span> secs elapsed...
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>ithome-6564f65698-947rv netutils Hello! &lt;span style="color:#ae81ff">368&lt;/span> secs elapsed...
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>ithome-6564f65698-k5wtg netutils Hello! &lt;span style="color:#ae81ff">370&lt;/span> secs elapsed...
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>ithome-6564f65698-rrvk4 netutils Hello! &lt;span style="color:#ae81ff">370&lt;/span> secs elapsed...
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>ithome-6564f65698-zhwlj netutils Hello! &lt;span style="color:#ae81ff">371&lt;/span> secs elapsed...
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>ithome-6564f65698-fglr9 netutils Hello! &lt;span style="color:#ae81ff">371&lt;/span> secs elapsed...
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>ithome-6564f65698-947rv netutils Hello! &lt;span style="color:#ae81ff">369&lt;/span> secs elapsed...
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>ithome-6564f65698-k5wtg netutils Hello! &lt;span style="color:#ae81ff">371&lt;/span> secs elapsed...
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>ithome-6564f65698-rrvk4 netutils Hello! &lt;span style="color:#ae81ff">371&lt;/span> secs elapsed...
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>ithome-6564f65698-zhwlj netutils Hello! &lt;span style="color:#ae81ff">372&lt;/span> secs elapsed...
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>ithome-6564f65698-fglr9 netutils Hello! &lt;span style="color:#ae81ff">372&lt;/span> secs elapsed...
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>^C
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="k9s">K9S&lt;/h4>
&lt;blockquote>
&lt;p>過往總是透過 kubectl 指令於各個資源，各 namespace 間切來切去，特別是要使用 &lt;code>exec&lt;/code>, &lt;code>get&lt;/code>, &lt;code>describe&lt;/code>, &lt;code>logs&lt;/code>, &lt;code>delete&lt;/code> 等指令時，常常打的手忙腳亂或是覺得心累，有這種困擾的人可以考慮使用看看 k9s 這個工具&lt;/p></description></item><item><title>值得了解的 5 個 DevSecOps 開源專案</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211130-5-devsecops-open-source-projects-know/</link><pubDate>Tue, 30 Nov 2021 12:41:13 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211130-5-devsecops-open-source-projects-know/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://enterprisersproject.com/article/2021/8/5-devsecops-open-source-projects-know" target="_blank" rel="noopener">值得了解的 5 個 DevSecOps 開源專案&lt;/a>&lt;/li>
&lt;/ul>
&lt;h4 id="clair">&lt;a href="https://github.com/quay/clair" target="_blank" rel="noopener">Clair&lt;/a>&lt;/h4>
&lt;h4 id="sigstore">&lt;a href="https://www.sigstore.dev/" target="_blank" rel="noopener">Sigstore&lt;/a>&lt;/h4>
&lt;h4 id="kubelinter">&lt;a href="https://github.com/stackrox/kube-linter" target="_blank" rel="noopener">KubeLinter&lt;/a>&lt;/h4>
&lt;h4 id="open-policy-agent-and-gatekeeper">&lt;a href="https://github.com/open-policy-agent/gatekeeper" target="_blank" rel="noopener">Open Policy Agent and Gatekeeper&lt;/a>&lt;/h4>
&lt;h4 id="falco">&lt;a href="https://falco.org/" target="_blank" rel="noopener">Falco&lt;/a>&lt;/h4></description></item><item><title>[Kubernetes] Service Overview</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211124-k8s-service-overview/</link><pubDate>Wed, 24 Nov 2021 14:00:45 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211124-k8s-service-overview/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://godleon.github.io/blog/Kubernetes/k8s-Service-Overview/" target="_blank" rel="noopener">[Kubernetes] Service Overview&lt;/a>&lt;/li>
&lt;/ul>
&lt;h3 id="定義-service">定義 Service&lt;/h3>
&lt;h4 id="搭配-selector">搭配 selector&lt;/h4>
&lt;blockquote>
&lt;p>由於要先有 Pod 才會有定義 Service 的需求，因此假設 k8s 中已經有一些 Pod 的存在(同時對外開放 TCP port 9376)，並帶有 app=MyApp 的 label，此時就可以定義一個 Service 來作為這些 pod 前方的抽象層，透過 domain name 的方式提供服務&lt;/p>&lt;/blockquote>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">kind&lt;/span>: &lt;span style="color:#ae81ff">Service&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">apiVersion&lt;/span>: &lt;span style="color:#ae81ff">v1&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">metadata&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">name&lt;/span>: &lt;span style="color:#ae81ff">my-service&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">spec&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># type 一共有四種(ClusterIP, NodePort, LoadBalancer, ExternalName)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># 預設是 ClusterIP&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">type&lt;/span>: &lt;span style="color:#ae81ff">ClusterIP&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># 選擇帶有 &amp;#34;app=MyApp&amp;#34; 的 pod&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">selector&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">app&lt;/span>: &lt;span style="color:#ae81ff">MyApp&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># Service 實際對外服務的設定&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">ports&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#f92672">protocol&lt;/span>: &lt;span style="color:#ae81ff">TCP&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">port&lt;/span>: &lt;span style="color:#ae81ff">80&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e"># 此為 Pod 對外開放的 port number&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">targetPort&lt;/span>: &lt;span style="color:#ae81ff">9376&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;code>Pod &amp;lt;---&amp;gt; Endpoint(tcp:9376) &amp;lt;---&amp;gt; Service(tcp:80, with VIP)&lt;/code>&lt;/p></description></item><item><title>25秒读取16GB文件，Go怎么做到的？</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211122-processing-16gb-file-in-seconds-go-lang/</link><pubDate>Mon, 22 Nov 2021 11:07:17 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211122-processing-16gb-file-in-seconds-go-lang/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://mp.weixin.qq.com/s/k6k9bwpKPdfShEEiTLSJ7w" target="_blank" rel="noopener">25 秒读取 16GB 文件，Go 怎么做到的？&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://medium.com/swlh/processing-16gb-file-in-seconds-go-lang-3982c235dfa2" target="_blank" rel="noopener">Reading 16GB File in Seconds, Golang&lt;/a>&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>打开文件后，我们有以下两个选项可以选择：&lt;/p>
&lt;ul>
&lt;li>逐行读取文件，这有助于减少内存紧张，但需要更多的时间。&lt;/li>
&lt;li>一次将整个文件读入内存并处理该文件，这将消耗更多内存，但会显著减少时间。&lt;/li>
&lt;/ul>
&lt;p>由于文件太大，即 16 GB，因此无法将整个文件加载到内存中。但是第一种选择对我们来说也是不可行的，因为我们希望在几秒钟内处理文件。&lt;/p>
&lt;p>但你猜怎么着，还有第三种选择。瞧……相比于将整个文件加载到内存中，在 Go 语言中，我们还可以使用 bufio.NewReader()将文件分块加载。&lt;/p>&lt;/blockquote>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">func&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">s&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">time&lt;/span>.&lt;span style="color:#a6e22e">Now&lt;/span>()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">args&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">os&lt;/span>.&lt;span style="color:#a6e22e">Args&lt;/span>[&lt;span style="color:#ae81ff">1&lt;/span>:]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> len(&lt;span style="color:#a6e22e">args&lt;/span>) &lt;span style="color:#f92672">!=&lt;/span> &lt;span style="color:#ae81ff">6&lt;/span> { &lt;span style="color:#75715e">// for format LogExtractor.exe -f &amp;#34;From Time&amp;#34; -t &amp;#34;To Time&amp;#34; -i &amp;#34;Log file directory location&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Println&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;Please give proper command line arguments&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">startTimeArg&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">args&lt;/span>[&lt;span style="color:#ae81ff">1&lt;/span>]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">finishTimeArg&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">args&lt;/span>[&lt;span style="color:#ae81ff">3&lt;/span>]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fileName&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">args&lt;/span>[&lt;span style="color:#ae81ff">5&lt;/span>]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">file&lt;/span>, &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">os&lt;/span>.&lt;span style="color:#a6e22e">Open&lt;/span>(&lt;span style="color:#a6e22e">fileName&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">!=&lt;/span> &lt;span style="color:#66d9ef">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Println&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;cannot able to read the file&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">err&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">defer&lt;/span> &lt;span style="color:#a6e22e">file&lt;/span>.&lt;span style="color:#a6e22e">Close&lt;/span>() &lt;span style="color:#75715e">// close after checking err&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">queryStartTime&lt;/span>, &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">time&lt;/span>.&lt;span style="color:#a6e22e">Parse&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;2006-01-02T15:04:05.0000Z&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">startTimeArg&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">!=&lt;/span> &lt;span style="color:#66d9ef">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Println&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;Could not able to parse the start time&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">startTimeArg&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">queryFinishTime&lt;/span>, &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">time&lt;/span>.&lt;span style="color:#a6e22e">Parse&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;2006-01-02T15:04:05.0000Z&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">finishTimeArg&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">!=&lt;/span> &lt;span style="color:#66d9ef">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Println&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;Could not able to parse the finish time&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">finishTimeArg&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">filestat&lt;/span>, &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">file&lt;/span>.&lt;span style="color:#a6e22e">Stat&lt;/span>()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">!=&lt;/span> &lt;span style="color:#66d9ef">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Println&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;Could not able to get the file stat&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fileSize&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">filestat&lt;/span>.&lt;span style="color:#a6e22e">Size&lt;/span>()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">offset&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">fileSize&lt;/span> &lt;span style="color:#f92672">-&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">lastLineSize&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">for&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">b&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> make([]&lt;span style="color:#66d9ef">byte&lt;/span>, &lt;span style="color:#ae81ff">1&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">n&lt;/span>, &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">file&lt;/span>.&lt;span style="color:#a6e22e">ReadAt&lt;/span>(&lt;span style="color:#a6e22e">b&lt;/span>, &lt;span style="color:#a6e22e">offset&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">!=&lt;/span> &lt;span style="color:#66d9ef">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Println&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;Error reading file &amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">err&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">break&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">char&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> string(&lt;span style="color:#a6e22e">b&lt;/span>[&lt;span style="color:#ae81ff">0&lt;/span>])
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">char&lt;/span> &lt;span style="color:#f92672">==&lt;/span> &lt;span style="color:#e6db74">&amp;#34;\n&amp;#34;&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">break&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">offset&lt;/span>&lt;span style="color:#f92672">--&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">lastLineSize&lt;/span> &lt;span style="color:#f92672">+=&lt;/span> &lt;span style="color:#a6e22e">n&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">lastLine&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> make([]&lt;span style="color:#66d9ef">byte&lt;/span>, &lt;span style="color:#a6e22e">lastLineSize&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">_&lt;/span>, &lt;span style="color:#a6e22e">err&lt;/span> = &lt;span style="color:#a6e22e">file&lt;/span>.&lt;span style="color:#a6e22e">ReadAt&lt;/span>(&lt;span style="color:#a6e22e">lastLine&lt;/span>, &lt;span style="color:#a6e22e">offset&lt;/span>&lt;span style="color:#f92672">+&lt;/span>&lt;span style="color:#ae81ff">1&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">!=&lt;/span> &lt;span style="color:#66d9ef">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Println&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;Could not able to read last line with offset&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">offset&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;and lastline size&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">lastLineSize&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">logSlice&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">strings&lt;/span>.&lt;span style="color:#a6e22e">SplitN&lt;/span>(string(&lt;span style="color:#a6e22e">lastLine&lt;/span>), &lt;span style="color:#e6db74">&amp;#34;,&amp;#34;&lt;/span>, &lt;span style="color:#ae81ff">2&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">logCreationTimeString&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">logSlice&lt;/span>[&lt;span style="color:#ae81ff">0&lt;/span>]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">lastLogCreationTime&lt;/span>, &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">time&lt;/span>.&lt;span style="color:#a6e22e">Parse&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;2006-01-02T15:04:05.0000Z&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">logCreationTimeString&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">!=&lt;/span> &lt;span style="color:#66d9ef">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Println&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;can not able to parse time : &amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">err&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">lastLogCreationTime&lt;/span>.&lt;span style="color:#a6e22e">After&lt;/span>(&lt;span style="color:#a6e22e">queryStartTime&lt;/span>) &lt;span style="color:#f92672">&amp;amp;&amp;amp;&lt;/span> &lt;span style="color:#a6e22e">lastLogCreationTime&lt;/span>.&lt;span style="color:#a6e22e">Before&lt;/span>(&lt;span style="color:#a6e22e">queryFinishTime&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Process&lt;/span>(&lt;span style="color:#a6e22e">file&lt;/span>, &lt;span style="color:#a6e22e">queryStartTime&lt;/span>, &lt;span style="color:#a6e22e">queryFinishTime&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Println&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;\nTime taken - &amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">time&lt;/span>.&lt;span style="color:#a6e22e">Since&lt;/span>(&lt;span style="color:#a6e22e">s&lt;/span>))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">func&lt;/span> &lt;span style="color:#a6e22e">Process&lt;/span>(&lt;span style="color:#a6e22e">f&lt;/span> &lt;span style="color:#f92672">*&lt;/span>&lt;span style="color:#a6e22e">os&lt;/span>.&lt;span style="color:#a6e22e">File&lt;/span>, &lt;span style="color:#a6e22e">start&lt;/span> &lt;span style="color:#a6e22e">time&lt;/span>.&lt;span style="color:#a6e22e">Time&lt;/span>, &lt;span style="color:#a6e22e">end&lt;/span> &lt;span style="color:#a6e22e">time&lt;/span>.&lt;span style="color:#a6e22e">Time&lt;/span>) &lt;span style="color:#66d9ef">error&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">linesPool&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">sync&lt;/span>.&lt;span style="color:#a6e22e">Pool&lt;/span>{&lt;span style="color:#a6e22e">New&lt;/span>: &lt;span style="color:#66d9ef">func&lt;/span>() &lt;span style="color:#66d9ef">interface&lt;/span>{} {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">lines&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> make([]&lt;span style="color:#66d9ef">byte&lt;/span>, &lt;span style="color:#ae81ff">250&lt;/span>&lt;span style="color:#f92672">*&lt;/span>&lt;span style="color:#ae81ff">1024&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#a6e22e">lines&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">stringPool&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">sync&lt;/span>.&lt;span style="color:#a6e22e">Pool&lt;/span>{&lt;span style="color:#a6e22e">New&lt;/span>: &lt;span style="color:#66d9ef">func&lt;/span>() &lt;span style="color:#66d9ef">interface&lt;/span>{} {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">lines&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#e6db74">&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#a6e22e">lines&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">r&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">bufio&lt;/span>.&lt;span style="color:#a6e22e">NewReader&lt;/span>(&lt;span style="color:#a6e22e">f&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">var&lt;/span> &lt;span style="color:#a6e22e">wg&lt;/span> &lt;span style="color:#a6e22e">sync&lt;/span>.&lt;span style="color:#a6e22e">WaitGroup&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">for&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">buf&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">linesPool&lt;/span>.&lt;span style="color:#a6e22e">Get&lt;/span>().([]&lt;span style="color:#66d9ef">byte&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">n&lt;/span>, &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">r&lt;/span>.&lt;span style="color:#a6e22e">Read&lt;/span>(&lt;span style="color:#a6e22e">buf&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">buf&lt;/span> = &lt;span style="color:#a6e22e">buf&lt;/span>[:&lt;span style="color:#a6e22e">n&lt;/span>]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">n&lt;/span> &lt;span style="color:#f92672">==&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">!=&lt;/span> &lt;span style="color:#66d9ef">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Println&lt;/span>(&lt;span style="color:#a6e22e">err&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">break&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">==&lt;/span> &lt;span style="color:#a6e22e">io&lt;/span>.&lt;span style="color:#a6e22e">EOF&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">break&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#a6e22e">err&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">nextUntillNewline&lt;/span>, &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">r&lt;/span>.&lt;span style="color:#a6e22e">ReadBytes&lt;/span>(&lt;span style="color:#e6db74">&amp;#39;\n&amp;#39;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">!=&lt;/span> &lt;span style="color:#a6e22e">io&lt;/span>.&lt;span style="color:#a6e22e">EOF&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">buf&lt;/span> = append(&lt;span style="color:#a6e22e">buf&lt;/span>, &lt;span style="color:#a6e22e">nextUntillNewline&lt;/span>&lt;span style="color:#f92672">...&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">wg&lt;/span>.&lt;span style="color:#a6e22e">Add&lt;/span>(&lt;span style="color:#ae81ff">1&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">go&lt;/span> &lt;span style="color:#66d9ef">func&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">ProcessChunk&lt;/span>(&lt;span style="color:#a6e22e">buf&lt;/span>, &lt;span style="color:#f92672">&amp;amp;&lt;/span>&lt;span style="color:#a6e22e">linesPool&lt;/span>, &lt;span style="color:#f92672">&amp;amp;&lt;/span>&lt;span style="color:#a6e22e">stringPool&lt;/span>, &lt;span style="color:#a6e22e">start&lt;/span>, &lt;span style="color:#a6e22e">end&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">wg&lt;/span>.&lt;span style="color:#a6e22e">Done&lt;/span>()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">wg&lt;/span>.&lt;span style="color:#a6e22e">Wait&lt;/span>()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#66d9ef">nil&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">func&lt;/span> &lt;span style="color:#a6e22e">ProcessChunk&lt;/span>(&lt;span style="color:#a6e22e">chunk&lt;/span> []&lt;span style="color:#66d9ef">byte&lt;/span>, &lt;span style="color:#a6e22e">linesPool&lt;/span> &lt;span style="color:#f92672">*&lt;/span>&lt;span style="color:#a6e22e">sync&lt;/span>.&lt;span style="color:#a6e22e">Pool&lt;/span>, &lt;span style="color:#a6e22e">stringPool&lt;/span> &lt;span style="color:#f92672">*&lt;/span>&lt;span style="color:#a6e22e">sync&lt;/span>.&lt;span style="color:#a6e22e">Pool&lt;/span>, &lt;span style="color:#a6e22e">start&lt;/span> &lt;span style="color:#a6e22e">time&lt;/span>.&lt;span style="color:#a6e22e">Time&lt;/span>, &lt;span style="color:#a6e22e">end&lt;/span> &lt;span style="color:#a6e22e">time&lt;/span>.&lt;span style="color:#a6e22e">Time&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">var&lt;/span> &lt;span style="color:#a6e22e">wg2&lt;/span> &lt;span style="color:#a6e22e">sync&lt;/span>.&lt;span style="color:#a6e22e">WaitGroup&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">logs&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">stringPool&lt;/span>.&lt;span style="color:#a6e22e">Get&lt;/span>().(&lt;span style="color:#66d9ef">string&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">logs&lt;/span> = string(&lt;span style="color:#a6e22e">chunk&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">linesPool&lt;/span>.&lt;span style="color:#a6e22e">Put&lt;/span>(&lt;span style="color:#a6e22e">chunk&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">logsSlice&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">strings&lt;/span>.&lt;span style="color:#a6e22e">Split&lt;/span>(&lt;span style="color:#a6e22e">logs&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;\n&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">stringPool&lt;/span>.&lt;span style="color:#a6e22e">Put&lt;/span>(&lt;span style="color:#a6e22e">logs&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">chunkSize&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#ae81ff">300&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">n&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> len(&lt;span style="color:#a6e22e">logsSlice&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">noOfThread&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">n&lt;/span> &lt;span style="color:#f92672">/&lt;/span> &lt;span style="color:#a6e22e">chunkSize&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">n&lt;/span>&lt;span style="color:#f92672">%&lt;/span>&lt;span style="color:#a6e22e">chunkSize&lt;/span> &lt;span style="color:#f92672">!=&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">noOfThread&lt;/span>&lt;span style="color:#f92672">++&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">for&lt;/span> &lt;span style="color:#a6e22e">i&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span>; &lt;span style="color:#a6e22e">i&lt;/span> &amp;lt; (&lt;span style="color:#a6e22e">noOfThread&lt;/span>); &lt;span style="color:#a6e22e">i&lt;/span>&lt;span style="color:#f92672">++&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">wg2&lt;/span>.&lt;span style="color:#a6e22e">Add&lt;/span>(&lt;span style="color:#ae81ff">1&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">go&lt;/span> &lt;span style="color:#66d9ef">func&lt;/span>(&lt;span style="color:#a6e22e">s&lt;/span> &lt;span style="color:#66d9ef">int&lt;/span>, &lt;span style="color:#a6e22e">e&lt;/span> &lt;span style="color:#66d9ef">int&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">defer&lt;/span> &lt;span style="color:#a6e22e">wg2&lt;/span>.&lt;span style="color:#a6e22e">Done&lt;/span>() &lt;span style="color:#75715e">// to avaoid deadlocks&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">for&lt;/span> &lt;span style="color:#a6e22e">i&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">s&lt;/span>; &lt;span style="color:#a6e22e">i&lt;/span> &amp;lt; &lt;span style="color:#a6e22e">e&lt;/span>; &lt;span style="color:#a6e22e">i&lt;/span>&lt;span style="color:#f92672">++&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">text&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">logsSlice&lt;/span>[&lt;span style="color:#a6e22e">i&lt;/span>]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> len(&lt;span style="color:#a6e22e">text&lt;/span>) &lt;span style="color:#f92672">==&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">continue&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">logSlice&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">strings&lt;/span>.&lt;span style="color:#a6e22e">SplitN&lt;/span>(&lt;span style="color:#a6e22e">text&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;,&amp;#34;&lt;/span>, &lt;span style="color:#ae81ff">2&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">logCreationTimeString&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">logSlice&lt;/span>[&lt;span style="color:#ae81ff">0&lt;/span>]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">logCreationTime&lt;/span>, &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">time&lt;/span>.&lt;span style="color:#a6e22e">Parse&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;2006-01-02T15:04:05.0000Z&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">logCreationTimeString&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">!=&lt;/span> &lt;span style="color:#66d9ef">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;\n Could not able to parse the time :%s for log : %v&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">logCreationTimeString&lt;/span>, &lt;span style="color:#a6e22e">text&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">logCreationTime&lt;/span>.&lt;span style="color:#a6e22e">After&lt;/span>(&lt;span style="color:#a6e22e">start&lt;/span>) &lt;span style="color:#f92672">&amp;amp;&amp;amp;&lt;/span> &lt;span style="color:#a6e22e">logCreationTime&lt;/span>.&lt;span style="color:#a6e22e">Before&lt;/span>(&lt;span style="color:#a6e22e">end&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// fmt.Println(text)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }(&lt;span style="color:#a6e22e">i&lt;/span>&lt;span style="color:#f92672">*&lt;/span>&lt;span style="color:#a6e22e">chunkSize&lt;/span>, int(&lt;span style="color:#a6e22e">math&lt;/span>.&lt;span style="color:#a6e22e">Min&lt;/span>(float64((&lt;span style="color:#a6e22e">i&lt;/span>&lt;span style="color:#f92672">+&lt;/span>&lt;span style="color:#ae81ff">1&lt;/span>)&lt;span style="color:#f92672">*&lt;/span>&lt;span style="color:#a6e22e">chunkSize&lt;/span>), float64(len(&lt;span style="color:#a6e22e">logsSlice&lt;/span>)))))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">wg2&lt;/span>.&lt;span style="color:#a6e22e">Wait&lt;/span>()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">logsSlice&lt;/span> = &lt;span style="color:#66d9ef">nil&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Gin 框架绑定 JSON 参数使用 jsoniter</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211122-go-gin-jsoniter/</link><pubDate>Mon, 22 Nov 2021 10:27:39 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211122-go-gin-jsoniter/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://mp.weixin.qq.com/s/nf9OYpN3f8HMDj_xkdCzdw" target="_blank" rel="noopener">Gin 框架绑定 JSON 参数使用 jsoniter&lt;/a>&lt;/li>
&lt;/ul>
&lt;h3 id="simple">simple&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>go build -tags&lt;span style="color:#f92672">=&lt;/span>jsoniter ./...
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="custom">custom&lt;/h3>
&lt;h4 id="implement-bindingbody-interface">implement &lt;code>BindingBody&lt;/code> interface&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// github.com/gin-gonic/gin@v1.6.3/binding/binding.go:36&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// Binding describes the interface which needs to be implemented for binding the&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// data present in the request such as JSON request body, query parameters or&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// the form POST.&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">type&lt;/span> &lt;span style="color:#a6e22e">Binding&lt;/span> &lt;span style="color:#66d9ef">interface&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Name&lt;/span>() &lt;span style="color:#66d9ef">string&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Bind&lt;/span>(&lt;span style="color:#f92672">*&lt;/span>&lt;span style="color:#a6e22e">http&lt;/span>.&lt;span style="color:#a6e22e">Request&lt;/span>, &lt;span style="color:#66d9ef">interface&lt;/span>{}) &lt;span style="color:#66d9ef">error&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// BindingBody adds BindBody method to Binding. BindBody is similar with Bind,&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// but it reads the body from supplied bytes instead of req.Body.&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">type&lt;/span> &lt;span style="color:#a6e22e">BindingBody&lt;/span> &lt;span style="color:#66d9ef">interface&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Binding&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">BindBody&lt;/span>([]&lt;span style="color:#66d9ef">byte&lt;/span>, &lt;span style="color:#66d9ef">interface&lt;/span>{}) &lt;span style="color:#66d9ef">error&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">package&lt;/span> &lt;span style="color:#a6e22e">custom&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> (
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;bytes&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;fmt&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;io&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;net/http&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">jsoniter&lt;/span> &lt;span style="color:#e6db74">&amp;#34;github.com/json-iterator/go&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;github.com/gin-gonic/gin/binding&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// BindingJSON 替换Gin默认的binding，支持更丰富JSON功能&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">var&lt;/span> &lt;span style="color:#a6e22e">BindingJSON&lt;/span> = &lt;span style="color:#a6e22e">jsonBinding&lt;/span>{}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// 可以自定义jsoniter配置或者添加插件&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">var&lt;/span> &lt;span style="color:#a6e22e">json&lt;/span> = &lt;span style="color:#a6e22e">jsoniter&lt;/span>.&lt;span style="color:#a6e22e">ConfigCompatibleWithStandardLibrary&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">type&lt;/span> &lt;span style="color:#a6e22e">jsonBinding&lt;/span> &lt;span style="color:#66d9ef">struct&lt;/span>{}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">func&lt;/span> (&lt;span style="color:#a6e22e">jsonBinding&lt;/span>) &lt;span style="color:#a6e22e">Name&lt;/span>() &lt;span style="color:#66d9ef">string&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#e6db74">&amp;#34;json&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">func&lt;/span> (&lt;span style="color:#a6e22e">jsonBinding&lt;/span>) &lt;span style="color:#a6e22e">Bind&lt;/span>(&lt;span style="color:#a6e22e">req&lt;/span> &lt;span style="color:#f92672">*&lt;/span>&lt;span style="color:#a6e22e">http&lt;/span>.&lt;span style="color:#a6e22e">Request&lt;/span>, &lt;span style="color:#a6e22e">obj&lt;/span> &lt;span style="color:#66d9ef">interface&lt;/span>{}) &lt;span style="color:#66d9ef">error&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">req&lt;/span> &lt;span style="color:#f92672">==&lt;/span> &lt;span style="color:#66d9ef">nil&lt;/span> &lt;span style="color:#f92672">||&lt;/span> &lt;span style="color:#a6e22e">req&lt;/span>.&lt;span style="color:#a6e22e">Body&lt;/span> &lt;span style="color:#f92672">==&lt;/span> &lt;span style="color:#66d9ef">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Errorf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;invalid request&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#a6e22e">decodeJSON&lt;/span>(&lt;span style="color:#a6e22e">req&lt;/span>.&lt;span style="color:#a6e22e">Body&lt;/span>, &lt;span style="color:#a6e22e">obj&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">func&lt;/span> (&lt;span style="color:#a6e22e">jsonBinding&lt;/span>) &lt;span style="color:#a6e22e">BindBody&lt;/span>(&lt;span style="color:#a6e22e">body&lt;/span> []&lt;span style="color:#66d9ef">byte&lt;/span>, &lt;span style="color:#a6e22e">obj&lt;/span> &lt;span style="color:#66d9ef">interface&lt;/span>{}) &lt;span style="color:#66d9ef">error&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#a6e22e">decodeJSON&lt;/span>(&lt;span style="color:#a6e22e">bytes&lt;/span>.&lt;span style="color:#a6e22e">NewReader&lt;/span>(&lt;span style="color:#a6e22e">body&lt;/span>), &lt;span style="color:#a6e22e">obj&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">func&lt;/span> &lt;span style="color:#a6e22e">decodeJSON&lt;/span>(&lt;span style="color:#a6e22e">r&lt;/span> &lt;span style="color:#a6e22e">io&lt;/span>.&lt;span style="color:#a6e22e">Reader&lt;/span>, &lt;span style="color:#a6e22e">obj&lt;/span> &lt;span style="color:#66d9ef">interface&lt;/span>{}) &lt;span style="color:#66d9ef">error&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">decoder&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">json&lt;/span>.&lt;span style="color:#a6e22e">NewDecoder&lt;/span>(&lt;span style="color:#a6e22e">r&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">binding&lt;/span>.&lt;span style="color:#a6e22e">EnableDecoderUseNumber&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">decoder&lt;/span>.&lt;span style="color:#a6e22e">UseNumber&lt;/span>()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">binding&lt;/span>.&lt;span style="color:#a6e22e">EnableDecoderDisallowUnknownFields&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">decoder&lt;/span>.&lt;span style="color:#a6e22e">DisallowUnknownFields&lt;/span>()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">decoder&lt;/span>.&lt;span style="color:#a6e22e">Decode&lt;/span>(&lt;span style="color:#a6e22e">obj&lt;/span>); &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">!=&lt;/span> &lt;span style="color:#66d9ef">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#a6e22e">err&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#a6e22e">validate&lt;/span>(&lt;span style="color:#a6e22e">obj&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">func&lt;/span> &lt;span style="color:#a6e22e">validate&lt;/span>(&lt;span style="color:#a6e22e">obj&lt;/span> &lt;span style="color:#66d9ef">interface&lt;/span>{}) &lt;span style="color:#66d9ef">error&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">binding&lt;/span>.&lt;span style="color:#a6e22e">Validator&lt;/span> &lt;span style="color:#f92672">==&lt;/span> &lt;span style="color:#66d9ef">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#66d9ef">nil&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#a6e22e">binding&lt;/span>.&lt;span style="color:#a6e22e">Validator&lt;/span>.&lt;span style="color:#a6e22e">ValidateStruct&lt;/span>(&lt;span style="color:#a6e22e">obj&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// binding.JSON 替换成自定义的&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">ctx&lt;/span>.&lt;span style="color:#a6e22e">ShouldBindWith&lt;/span>(&lt;span style="color:#a6e22e">ms&lt;/span>, &lt;span style="color:#a6e22e">binding&lt;/span>.&lt;span style="color:#a6e22e">JSON&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">ctx&lt;/span>.&lt;span style="color:#a6e22e">ShouldBindBodyWith&lt;/span>(&lt;span style="color:#a6e22e">ms&lt;/span>, &lt;span style="color:#a6e22e">binding&lt;/span>.&lt;span style="color:#a6e22e">JSON&lt;/span>)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Nginx 筆記</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211119-nginx/</link><pubDate>Fri, 19 Nov 2021 14:35:58 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211119-nginx/</guid><description>&lt;h1 id="紀錄-nginx-設定檔及說明">紀錄 Nginx 設定檔及說明&lt;/h1>
&lt;h2 id="檔案結構">檔案結構&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>.
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>├── geoip.conf
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>├── nginx.conf
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>├── sites-available
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│ ├── default.conf
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>├── sites-enabled
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│ ├── default.conf -&amp;gt; ../sites-available/default.conf
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>├── upstream.conf
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="geoipconf">geoip.conf&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-nginx" data-lang="nginx">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">## module: ngx_http_geoip2_module
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">## https://github.com/leev/ngx_http_geoip2_module
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">## 讀取 GeoIP 資料庫，並進行變數設定
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#66d9ef">geoip2&lt;/span> &lt;span style="color:#e6db74">/usr/share/GeoIP/GeoLite2-Country.mmdb&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">auto_reload&lt;/span> &lt;span style="color:#ae81ff">60m&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">$geoip2_metadata_country_build&lt;/span> &lt;span style="color:#e6db74">metadata&lt;/span> &lt;span style="color:#e6db74">build_epoch&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## 自定義 $geoip2_data_country_code 值為 $remote_addr 對應的 ISO 3116 規範的國碼
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">$geoip2_data_country_code&lt;/span> &lt;span style="color:#e6db74">source=&lt;/span>$remote_addr &lt;span style="color:#e6db74">country&lt;/span> &lt;span style="color:#e6db74">iso_code&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## 自定義 $geoip2_data_country_name 值為對應的英文城市名
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">$geoip2_data_country_name&lt;/span> &lt;span style="color:#e6db74">country&lt;/span> &lt;span style="color:#e6db74">names&lt;/span> &lt;span style="color:#e6db74">en&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="upstreamconf">upstream.conf&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-nginx" data-lang="nginx">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">## module: ngx_http_upstream_module
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">## 定義 server 組別
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#66d9ef">upstream&lt;/span> &lt;span style="color:#e6db74">to_nodejs1&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## server address [parameters]; 定義 server
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#75715e">## parameters:
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#75715e">## weight=number 定義權重，預設為 1
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#75715e">## max_fails=number 設定到 upstream server 的最大重試次數，預設為 1
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#75715e">## fail_timeout=time 設定到達 max_fails 次數之後，暫停向此 upstream server 傳送請求的時間，預設為 10 秒
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#75715e">## backup 標記此 upstream server 為備用，當其他 upstream server 不可用時，此 upstream server 可接受請求
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#75715e">## down 標記此 upstream server 為不可用
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">server&lt;/span> 10.7.0.12:&lt;span style="color:#ae81ff">90&lt;/span> &lt;span style="color:#e6db74">max_fails=3&lt;/span> &lt;span style="color:#e6db74">fail_timeout=5s&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">server&lt;/span> 10.7.0.12:&lt;span style="color:#ae81ff">91&lt;/span> &lt;span style="color:#e6db74">max_fails=3&lt;/span> &lt;span style="color:#e6db74">fail_timeout=5s&lt;/span> &lt;span style="color:#e6db74">backup&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">upstream&lt;/span> &lt;span style="color:#e6db74">to_nodejs2&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">server&lt;/span> 10.7.0.12:&lt;span style="color:#ae81ff">92&lt;/span> &lt;span style="color:#e6db74">max_fails=3&lt;/span> &lt;span style="color:#e6db74">fail_timeout=5s&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">server&lt;/span> 10.7.0.12:&lt;span style="color:#ae81ff">93&lt;/span> &lt;span style="color:#e6db74">max_fails=3&lt;/span> &lt;span style="color:#e6db74">fail_timeout=5s&lt;/span> &lt;span style="color:#e6db74">backup&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">upstream&lt;/span> &lt;span style="color:#e6db74">to_nodejs95&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">server&lt;/span> 10.7.0.12:&lt;span style="color:#ae81ff">95&lt;/span> &lt;span style="color:#e6db74">max_fails=3&lt;/span> &lt;span style="color:#e6db74">fail_timeout=5s&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">## module: ngx_http_map_module
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">## map string $variable { ... } 建立一個新的變數
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#66d9ef">map&lt;/span> $arg_agent $game_api {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## $arg_agent 請求中 agent 的值(https://abc.com/?agent=123)
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#75715e">## agent=60037, $game_api 的值為 to_nodejs95
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">60037&lt;/span> &lt;span style="color:#e6db74">to_nodejs95&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## agent 結尾是 1, 2, 3, 或是 4, $game_api 的值為 to_nodejs1
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">~*1$&lt;/span> &lt;span style="color:#e6db74">to_nodejs1&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">~*2$&lt;/span> &lt;span style="color:#e6db74">to_nodejs1&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">~*3$&lt;/span> &lt;span style="color:#e6db74">to_nodejs1&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">~*4$&lt;/span> &lt;span style="color:#e6db74">to_nodejs1&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## 若 agent 不符合上開規則，預設 $game_api 的值為 to_nodejs2
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">default&lt;/span> &lt;span style="color:#e6db74">to_nodejs2&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="defaultconf">default.conf&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-nginx" data-lang="nginx">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">## module: ngx_http_limit_req_module
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">## 限制請求處理
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">## limit_req_zone key zone=name:size rate=rate [sync]; 定義限制請求的規則
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#66d9ef">limit_req_zone&lt;/span> $binary_remote_addr$server_name &lt;span style="color:#e6db74">zone=websocket:10m&lt;/span> &lt;span style="color:#e6db74">rate=1r/m&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">## limit_req_status code; 設定被拒絕連線的 HTTP 狀態碼，預設為 503
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#66d9ef">limit_req_status&lt;/span> &lt;span style="color:#ae81ff">502&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">## 設定虛擬主機
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#66d9ef">server&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## listen port [default_server] [ssl] [http2 | spdy] [proxy_protocol] [setfib=number] [fastopen=number] [backlog=number] [rcvbuf=size] [sndbuf=size] [accept_filter=filter] [deferred] [bind] [ipv6only=on|off] [reuseport] [so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt]];
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#75715e">## 設定監聽的埠口，預設為 *:80
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#75715e">## 下方設定為監聽 80 port，且為預設的虛擬主機
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">listen&lt;/span> &lt;span style="color:#ae81ff">80&lt;/span> &lt;span style="color:#e6db74">default_server&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## server_name name ...; 設定虛擬主機名，可使用正則表示式，預設為 &amp;#34;&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">server_name&lt;/span> &lt;span style="color:#e6db74">_&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">access_log&lt;/span> &lt;span style="color:#e6db74">logs/default/default.log&lt;/span> &lt;span style="color:#e6db74">json&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">error_log&lt;/span> &lt;span style="color:#e6db74">logs/default/default.error.log&lt;/span> &lt;span style="color:#e6db74">warn&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## module: ngx_http_access_module
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#75715e">## allow address | CIDR | unix: | all; 允許 IP 訪問
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">allow&lt;/span> 1.1.1.1;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## deny address | CIDR | unix: | all; 禁止 IP 訪問
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">deny&lt;/span> 12.34.56.78;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## 設定請求訪問的根資料夾
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">root&lt;/span> &lt;span style="color:#e6db74">/usr/share/nginx/html&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## limit_req zone=name [burst=number] [nodelay | delay=number]; 設定限制請求的規則 zone
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">limit_req&lt;/span> &lt;span style="color:#e6db74">zone=websocket&lt;/span> &lt;span style="color:#e6db74">nodelay&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## limit_req_log_level info | notice | warn | error; 設定被拒絕連線的請求日誌等級，預設為 error
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">limit_req_log_level&lt;/span> &lt;span style="color:#e6db74">warn&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## location [ = | ~ | ~* | ^~ ] uri { ... }
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#75715e">## location @name { ... } 依據請求的 URI 配置
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">location&lt;/span> &lt;span style="color:#e6db74">/&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">default_type&lt;/span> &lt;span style="color:#e6db74">application/json&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## 返回 HTTP 狀態碼 200，並包含字串
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">return&lt;/span> &lt;span style="color:#ae81ff">200&lt;/span> &lt;span style="color:#e6db74">&amp;#39;&lt;/span>{&lt;span style="color:#f92672">&amp;#34;Code&amp;#34;:&lt;/span> &lt;span style="color:#e6db74">&amp;#34;&lt;/span>$status&amp;#34;, &lt;span style="color:#e6db74">&amp;#34;IP&amp;#34;:&lt;/span> &lt;span style="color:#e6db74">&amp;#34;&lt;/span>$remote_addr&amp;#34;}&amp;#39;;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">server&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## 下方設定為監聽 443 port，且為預設的虛擬主機，所有連線都使用 SSL
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">listen&lt;/span> &lt;span style="color:#ae81ff">443&lt;/span> &lt;span style="color:#e6db74">default_server&lt;/span> &lt;span style="color:#e6db74">ssl&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">server_name&lt;/span> &lt;span style="color:#e6db74">_&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">access_log&lt;/span> &lt;span style="color:#e6db74">logs/default/default.log&lt;/span> &lt;span style="color:#e6db74">json&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">error_log&lt;/span> &lt;span style="color:#e6db74">logs/default/default.error.log&lt;/span> &lt;span style="color:#e6db74">warn&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## module: ngx_http_ssl_module
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#75715e">## 設定 PEM 格式的證書
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">ssl_certificate&lt;/span> &lt;span style="color:#e6db74">/etc/ssl/hddv1.com.crt&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## 設定 PEM 格式的密鑰
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">ssl_certificate_key&lt;/span> &lt;span style="color:#e6db74">/etc/ssl/hddv1.com.key&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## 設定 SSL 版本，預設為 TLSv1 TLSv1.1 TLSv1.2
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">ssl_protocols&lt;/span> &lt;span style="color:#e6db74">TLSv1.2&lt;/span> &lt;span style="color:#e6db74">TLSv1.3&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## 設定啟用的加密方法，預設為 HIGH:!aNULL:!MD5
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">ssl_ciphers&lt;/span> &lt;span style="color:#e6db74">&amp;#34;EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH+aRSA+RC4:EECDH:EDH+aRSA:HIGH:!RC2:!RC4:!aNULL:!eNULL:!LOW:!IDEA:!DES:!TDES:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!EXPORT:!ANON&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## 為 DHE 加密法指定帶有 DH 參數的文件
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">ssl_dhparam&lt;/span> &lt;span style="color:#e6db74">/etc/ssl/dhparams.pem&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## 是否優先使用 server 的加密法，預設為 off
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">ssl_prefer_server_ciphers&lt;/span> &lt;span style="color:#66d9ef">on&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## ssl_session_cache off | none | [builtin[:size]] [shared:name:size];
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#75715e">## 設定緩存及大小，預設為 none
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">ssl_session_cache&lt;/span> &lt;span style="color:#e6db74">shared:SSL:1m&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## 設定 session 可重複使用的時間，預設為 5 分鐘
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">ssl_session_timeout&lt;/span> &lt;span style="color:#ae81ff">5m&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">add_header&lt;/span> &lt;span style="color:#e6db74">X-Frame-Options&lt;/span> &lt;span style="color:#e6db74">&amp;#34;SAMEORIGIN&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">add_header&lt;/span> &lt;span style="color:#e6db74">X-XSS-Protection&lt;/span> &lt;span style="color:#e6db74">&amp;#34;1&lt;/span>; &lt;span style="color:#f92672">mode=block&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">add_header&lt;/span> &lt;span style="color:#e6db74">Strict-Transport-Security&lt;/span> &lt;span style="color:#e6db74">&amp;#34;max-age=31536000&lt;/span>; &lt;span style="color:#f92672">includeSubdomains&lt;/span>; &lt;span style="color:#f92672">preload&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">root&lt;/span> &lt;span style="color:#e6db74">/usr/share/nginx/html&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">limit_req&lt;/span> &lt;span style="color:#e6db74">zone=websocket&lt;/span> &lt;span style="color:#e6db74">nodelay&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">limit_req_log_level&lt;/span> &lt;span style="color:#e6db74">warn&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">default_type&lt;/span> &lt;span style="color:#e6db74">application/json&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">location&lt;/span> &lt;span style="color:#e6db74">/&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">default_type&lt;/span> &lt;span style="color:#e6db74">application/json&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">return&lt;/span> &lt;span style="color:#ae81ff">200&lt;/span> &lt;span style="color:#e6db74">&amp;#39;&lt;/span>{&lt;span style="color:#f92672">&amp;#34;Code&amp;#34;:&lt;/span> &lt;span style="color:#e6db74">&amp;#34;&lt;/span>$status&amp;#34;, &lt;span style="color:#e6db74">&amp;#34;IP&amp;#34;:&lt;/span> &lt;span style="color:#e6db74">&amp;#34;&lt;/span>$remote_addr&amp;#34;}&amp;#39;;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="nginxconf">nginx.conf&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-nginx" data-lang="nginx">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">## module: ngx_core_module
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">## worker_processes number | auto; 啟動 Nginx worker 程序數量, 設定 auto 即和 CPU 的數量相等
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#66d9ef">worker_processes&lt;/span> &lt;span style="color:#e6db74">auto&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">## worker_rlimit_nofile number; Nginx worker 程序最大打開文件數，預設為系統 RLIMIT_NOFILE
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#66d9ef">worker_rlimit_nofile&lt;/span> &lt;span style="color:#ae81ff">131072&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">## worker_shutdown_timeout time; 設定關閉超時時間，當執行 reload 或是其他相關指令，超過 time 時間之後，Nginx 會主動關閉所有受影響的 worker
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#66d9ef">worker_shutdown_timeout&lt;/span> &lt;span style="color:#ae81ff">60&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">## error_log file [level]; 設定錯誤日誌寫入位置
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">## debug, info, notice, warn, error, crit, alert, emerg
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#66d9ef">error_log&lt;/span> &lt;span style="color:#e6db74">logs/error.log&lt;/span> &lt;span style="color:#e6db74">warn&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">## pid file; 主程序 ID 文件位置
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#66d9ef">pid&lt;/span> &lt;span style="color:#e6db74">logs/nginx.pid&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">## module: ngx_core_module
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">## 設定連線處理相關
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#66d9ef">events&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## worker_connections number; 單個 Nginx worker 程序的最大並發連接數，預設為 512，需要小於 worker_rlimit_nofile
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#75715e">## 最大連接數 = worker_connections * worker_processes
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">worker_connections&lt;/span> &lt;span style="color:#ae81ff">102400&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## accept_mutex on | off; 預設為 off
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#75715e">## 只有一個新連線進入，如果設定為 on，只有一個 worker 會接受連線，其餘持續休眠
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#75715e">## 如果設定為 off，所有 worker 會被喚醒，只有一個 worker 會接受連線，其餘重新休眠
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#75715e">## 業務上使用 TCP 長連線、流量大，off 的效能以及 QPS 表現較佳
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">accept_mutex&lt;/span> &lt;span style="color:#66d9ef">off&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## multi_accept on | off; 是否同時接受所有的請求，預設為 off
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">multi_accept&lt;/span> &lt;span style="color:#66d9ef">on&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">## module: ngx_http_core_module
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">## 設定 HTTP server 相關
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#66d9ef">http&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## module: ngx_core_module
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#75715e">## include file | mask; 使用文件中的設定
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#75715e">## 下方為設定 MIME 類型,類型由 mime.type 文件定義
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">include&lt;/span> &lt;span style="color:#e6db74">mime.types&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## default_type mime-type; 定義默認 MIME 類型，預設為 text/plain
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">default_type&lt;/span> &lt;span style="color:#e6db74">application/octet-stream&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## server_names_hash_max_size size; 設定 server_name 的 hash 表最大值，預設為 512 kb
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">server_names_hash_max_size&lt;/span> &lt;span style="color:#ae81ff">2048&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## 設定 server_name 的 hash 表的大小，用於快速找到對應的 server_name，預設值取決於 CPU 的 L1 cache
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">server_names_hash_bucket_size&lt;/span> &lt;span style="color:#ae81ff">256&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## server_tokens on | off | build | string; 是否在 Nginx 錯誤頁面顯示 Nginx 版本，預設為 on
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">server_tokens&lt;/span> &lt;span style="color:#66d9ef">off&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## 是否在錯誤日誌記錄 404
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">log_not_found&lt;/span> &lt;span style="color:#66d9ef">off&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## 是否啟用 sendfile() 提高文件傳輸效率，預設為 off
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">sendfile&lt;/span> &lt;span style="color:#66d9ef">on&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## 文件是否使用完整封包發送，預設為 off
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">tcp_nopush&lt;/span> &lt;span style="color:#66d9ef">on&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## 數據是否儘快傳送，預設為 on
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">tcp_nodelay&lt;/span> &lt;span style="color:#66d9ef">on&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## 設定長連線持續秒數，超過時間 Nginx 會主動關閉連線，預設為 75
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">keepalive_timeout&lt;/span> &lt;span style="color:#ae81ff">70&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## client_max_body_size size; 設定請求允許最大的 body 大小
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">client_max_body_size&lt;/span> &lt;span style="color:#e6db74">64M&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## module: ngx_http_gzip_module
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#75715e">## 是否啟用 gzip 壓縮，預設為 off
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">gzip&lt;/span> &lt;span style="color:#66d9ef">on&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## 設定要壓縮的 Content-Length 最小值，預設為 20
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">gzip_min_length&lt;/span> &lt;span style="color:#ae81ff">1k&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## 設定壓縮緩衝大小，預設為一頁記憶體
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#75715e">## gzip_buffers number size;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">gzip_buffers&lt;/span> &lt;span style="color:#ae81ff">4&lt;/span> &lt;span style="color:#ae81ff">32k&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## 設定壓縮等級，範圍 1 ~ 9，預設為 1
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">gzip_comp_level&lt;/span> &lt;span style="color:#ae81ff">7&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## 設定要壓縮的 MIME 類型，預設為 text/html
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">gzip_types&lt;/span> &lt;span style="color:#e6db74">text/plain&lt;/span> &lt;span style="color:#e6db74">application/x-javascript&lt;/span> &lt;span style="color:#e6db74">text/css&lt;/span> &lt;span style="color:#e6db74">application/xml&lt;/span> &lt;span style="color:#e6db74">text/javascript&lt;/span> &lt;span style="color:#e6db74">application/x-httpd-php&lt;/span> &lt;span style="color:#e6db74">application/json&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## 是否在 HTTP response header 增加 Vary: Accept-Encoding，預設為 off
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">gzip_vary&lt;/span> &lt;span style="color:#66d9ef">on&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## 針對特定 User-Agent 禁用壓縮
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#75715e">## 下方為設定禁用 IE 6
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">gzip_disable&lt;/span> &lt;span style="color:#e6db74">&amp;#34;MSIE&lt;/span> &lt;span style="color:#e6db74">[1-6]\.&amp;#34;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## resolver address ... [valid=time] [ipv6=on|off] [status_zone=zone]; 使用指定的 NS 解析 server_name, upstream server 等
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">resolver&lt;/span> 114.114.114.114 8.8.8.8 1.1.1.1;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## module: ngx_http_headers_module
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#75715e">## add_header name value [always]; 在 HTTP response header 增加欄位
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#75715e">## 下方為設定允許跨域
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">add_header&lt;/span> &lt;span style="color:#e6db74">Access-Control-Allow-Origin&lt;/span> &lt;span style="color:#e6db74">*&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">add_header&lt;/span> &lt;span style="color:#e6db74">Access-Control-Allow-Headers&lt;/span> &lt;span style="color:#e6db74">DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">add_header&lt;/span> &lt;span style="color:#e6db74">Access-Control-Allow-Methods&lt;/span> &lt;span style="color:#e6db74">GET,POST,OPTIONS&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">add_header&lt;/span> &lt;span style="color:#e6db74">Access-Control-Expose-Headers&lt;/span> &lt;span style="color:#e6db74">&amp;#39;WWW-Authenticate,Server-Authorization,User-Identity-Token&amp;#39;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## module: ngx_http_realip_module
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#75715e">## set_real_ip_from address | CIDR | unix:; 設定信任的可被替代的伺服器 IP，如反向代理伺服器
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">set_real_ip_from&lt;/span> 10.0.0.0&lt;span style="color:#e6db74">/8&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">set_real_ip_from&lt;/span> 172.16.0.0&lt;span style="color:#e6db74">/12&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">set_real_ip_from&lt;/span> 192.168.0.0&lt;span style="color:#e6db74">/16&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## real_ip_header field | X-Real-IP | X-Forwarded-For | proxy_protocol; 定義使用哪個標頭取代獲取到的 client IP，預設為 X-Real-IP
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">real_ip_header&lt;/span> &lt;span style="color:#e6db74">X-Forwarded-For&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## 將 real_ip_header 設定的標頭中，「最後一個非信任伺服器 IP」或是「最後一個 IP」當成真實 IP，預設為 off
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">real_ip_recursive&lt;/span> &lt;span style="color:#66d9ef">on&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## module: ngx_http_log_module
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#75715e">## log_format name [escape=default|json|none] string ...; 設定日誌格式
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">log_format&lt;/span> &lt;span style="color:#e6db74">json&lt;/span> &lt;span style="color:#e6db74">escape=json&lt;/span> &lt;span style="color:#e6db74">&amp;#39;&lt;/span>{&lt;span style="color:#f92672">&amp;#34;@timestamp&amp;#34;:&amp;#34;$time_iso8601&amp;#34;,&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#39;&amp;#34;@source&amp;#34;:&amp;#34;&lt;/span>$server_addr&amp;#34;,&amp;#39;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#39;&amp;#34;ip&amp;#34;:&amp;#34;&lt;/span>$http_x_forwarded_for&amp;#34;,&amp;#39;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#39;&amp;#34;client&amp;#34;:&amp;#34;&lt;/span>$remote_addr&amp;#34;,&amp;#39;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#39;&amp;#34;request_method&amp;#34;:&amp;#34;&lt;/span>$request_method&amp;#34;,&amp;#39;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#39;&amp;#34;scheme&amp;#34;:&amp;#34;&lt;/span>$scheme&amp;#34;,&amp;#39;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#39;&amp;#34;domain&amp;#34;:&amp;#34;&lt;/span>$server_name&amp;#34;,&amp;#39;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#39;&amp;#34;client_host&amp;#34;:&amp;#34;&lt;/span>$host&amp;#34;,&amp;#39;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#39;&amp;#34;referer&amp;#34;:&amp;#34;&lt;/span>$http_referer&amp;#34;,&amp;#39;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#39;&amp;#34;request&amp;#34;:&amp;#34;&lt;/span>$request_uri&amp;#34;,&amp;#39;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#39;&amp;#34;args&amp;#34;:&amp;#34;&lt;/span>$args&amp;#34;,&amp;#39;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#39;&amp;#34;sent_bytes&amp;#34;:&lt;/span>$body_bytes_sent,&amp;#39;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#39;&amp;#34;status&amp;#34;:&lt;/span>$status,&amp;#39;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#39;&amp;#34;responsetime&amp;#34;:&lt;/span>$request_time,&amp;#39;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#39;&amp;#34;upstreamtime&amp;#34;:&amp;#34;&lt;/span>$upstream_response_time&amp;#34;,&amp;#39;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#39;&amp;#34;upstreamaddr&amp;#34;:&amp;#34;&lt;/span>$upstream_addr&amp;#34;,&amp;#39;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#39;&amp;#34;http_user_agent&amp;#34;:&amp;#34;&lt;/span>$http_user_agent&amp;#34;,&amp;#39;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#39;&amp;#34;Country&amp;#34;:&amp;#34;&lt;/span>$geoip2_data_country_name&amp;#34;,&amp;#39;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#39;&amp;#34;State&amp;#34;:&amp;#34;&lt;/span>$geoip2_data_state_name&amp;#34;,&amp;#39;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#39;&amp;#34;City&amp;#34;:&amp;#34;&lt;/span>$geoip2_data_city_name&amp;#34;,&amp;#39;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#39;&amp;#34;all_agent&amp;#34;:&amp;#34;&lt;/span>$arg_agent&amp;#34;,&amp;#39;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#39;&amp;#34;dfw_agent&amp;#34;:&amp;#34;&lt;/span>$arg_proxy&amp;#34;,&amp;#39;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#39;&amp;#34;nw2_agent&amp;#34;:&amp;#34;&lt;/span>$arg_channel&amp;#34;,&amp;#39;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#39;&amp;#34;https&amp;#34;:&amp;#34;&lt;/span>$https&amp;#34;&amp;#39;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#39;&lt;/span>&lt;span style="color:#960050;background-color:#1e0010">}&lt;/span>&lt;span style="color:#e6db74">&amp;#39;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">log_format&lt;/span> &lt;span style="color:#e6db74">main&lt;/span> &lt;span style="color:#e6db74">&amp;#39;&lt;/span>$remote_addr &lt;span style="color:#e6db74">-&lt;/span> $remote_user &lt;span style="color:#e6db74">[&lt;/span>$time_local] &lt;span style="color:#e6db74">&amp;#34;&lt;/span>$request&amp;#34; &lt;span style="color:#e6db74">&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#39;&lt;/span>$status $body_bytes_sent &lt;span style="color:#e6db74">&amp;#34;&lt;/span>$http_referer&amp;#34; &lt;span style="color:#e6db74">&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#39;&amp;#34;&lt;/span>$http_user_agent&amp;#34; &lt;span style="color:#e6db74">&amp;#34;&lt;/span>$http_x_forwarded_for&amp;#34;&amp;#39;;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">## access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]]; 設定日誌寫入位置以及使用的日誌名稱
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#75715e">## access_log off; 不紀錄日誌
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span> &lt;span style="color:#f92672">access_log&lt;/span> &lt;span style="color:#e6db74">logs/access.log&lt;/span> &lt;span style="color:#e6db74">json&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Golang os/exec 使用方法（筆記）</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211112-golang-ex-exec/</link><pubDate>Fri, 12 Nov 2021 11:34:30 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211112-golang-ex-exec/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://124.244.86.40/wordpress/2020/10/25/golang-ex-exec-%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95%EF%BC%88%E7%AD%86%E8%A8%98%EF%BC%89/" target="_blank" rel="noopener">Golang os/exec 使用方法（筆記）&lt;/a>&lt;/li>
&lt;/ul>
&lt;h4 id="加入額外的環境參數再執行指令">加入額外的環境參數再執行指令&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">cmd&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">exec&lt;/span>.&lt;span style="color:#a6e22e">Command&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;programToExecute&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">additionalEnv&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#e6db74">&amp;#34;FOO=bar&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">newEnv&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> append(&lt;span style="color:#a6e22e">os&lt;/span>.&lt;span style="color:#a6e22e">Environ&lt;/span>(), &lt;span style="color:#a6e22e">additionalEnv&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">cmd&lt;/span>.&lt;span style="color:#a6e22e">Env&lt;/span> = &lt;span style="color:#a6e22e">newEnv&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">out&lt;/span>, &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">cmd&lt;/span>.&lt;span style="color:#a6e22e">CombinedOutput&lt;/span>()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">!=&lt;/span> &lt;span style="color:#66d9ef">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">log&lt;/span>.&lt;span style="color:#a6e22e">Fatalf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;cmd.Run() failed with %s\n&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">err&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;%s&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">out&lt;/span>)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="在-linux-下使用-osexec--pipe-或-bash-運算式">在 Linux 下使用 os/exec + Pipe 或 Bash 運算式&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">rcmd&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#e6db74">`iw dev | awk &amp;#39;$1==&amp;#34;Interface&amp;#34;{print $2}&amp;#39;`&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">cmd&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">exec&lt;/span>.&lt;span style="color:#a6e22e">Command&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;bash&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;-c&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">rcmd&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">out&lt;/span>, &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">cmd&lt;/span>.&lt;span style="color:#a6e22e">CombinedOutput&lt;/span>()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">!=&lt;/span> &lt;span style="color:#66d9ef">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">log&lt;/span>.&lt;span style="color:#a6e22e">Println&lt;/span>(&lt;span style="color:#a6e22e">err&lt;/span>.&lt;span style="color:#a6e22e">Error&lt;/span>())
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">log&lt;/span>.&lt;span style="color:#a6e22e">Println&lt;/span>(string(&lt;span style="color:#a6e22e">out&lt;/span>))
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="在-windows-下使用-osexec--batch-運算式">在 Windows 下使用 os/exec + Batch 運算式&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">cmd&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">exec&lt;/span>.&lt;span style="color:#a6e22e">Command&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;cmd&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;/c&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;ffmpeg -i myfile.mp4 myfile.mp3 &amp;amp;&amp;amp; del myfile.mp4&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">out&lt;/span>, &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">cmd&lt;/span>.&lt;span style="color:#a6e22e">CombinedOutput&lt;/span>()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">!=&lt;/span> &lt;span style="color:#66d9ef">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">log&lt;/span>.&lt;span style="color:#a6e22e">Println&lt;/span>(&lt;span style="color:#a6e22e">err&lt;/span>.&lt;span style="color:#a6e22e">Error&lt;/span>())
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">log&lt;/span>.&lt;span style="color:#a6e22e">Println&lt;/span>(string(&lt;span style="color:#a6e22e">out&lt;/span>))
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="解決-windows-cmd-在-osexec-時會出現本地語言的問題">解決 Windows CMD 在 os/exec 時會出現本地語言的問題&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">cmd&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">exec&lt;/span>.&lt;span style="color:#a6e22e">Command&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;cmd&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;/c&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;chcp 65001 &amp;amp;&amp;amp; netsh WLAN show drivers&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">out&lt;/span>, &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">cmd&lt;/span>.&lt;span style="color:#a6e22e">CombinedOutput&lt;/span>()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">!=&lt;/span> &lt;span style="color:#66d9ef">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">log&lt;/span>.&lt;span style="color:#a6e22e">Println&lt;/span>(&lt;span style="color:#a6e22e">err&lt;/span>.&lt;span style="color:#a6e22e">Error&lt;/span>())
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">log&lt;/span>.&lt;span style="color:#a6e22e">Println&lt;/span>(string(&lt;span style="color:#a6e22e">out&lt;/span>))
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>使用此方法得出的 output string 請記得把回傳的首行（chcp 的回傳結果）刪除掉再進行其他處理和讀取。&lt;/p></description></item><item><title>喬叔教 Elastic - 30 - Elasticsearch 的優化技巧 (4/4) - Shard 的最佳化管理</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211110-10253348/</link><pubDate>Wed, 10 Nov 2021 13:12:35 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211110-10253348/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://ithelp.ithome.com.tw/articles/10253348" target="_blank" rel="noopener">喬叔教 Elastic - 30 - Elasticsearch 的優化技巧 (4/4) - Shard 的最佳化管理&lt;/a>&lt;/li>
&lt;/ul>
&lt;h4 id="規劃時建議要考量的項目">規劃時建議要考量的項目&lt;/h4>
&lt;h5 id="search-在執行時一個-shard-會分配一個-thread數量太多反而會拖慢速度">Search 在執行時，一個 Shard 會分配一個 Thread，數量太多反而會拖慢速度&lt;/h5>
&lt;blockquote>
&lt;p>一個 Node 依照不同的功能分類有多種 Thread pool， 其中 search (count/search/suggest) 的 size 是 &lt;code>int((# of allocated processors * 3) / 2) + 1&lt;/code> 並且 queue_size 預設是 &lt;code>1000&lt;/code> ，而 write (index/delete/update/bulk) 的 size 是 &lt;code># of allocated processors&lt;/code> ，預設的 queue_size 也是 &lt;code>1000&lt;/code>。( 官方文件 - Thread pools )&lt;/p>&lt;/blockquote>
&lt;p>大多數的 searching 在執行時，查詢的資料是會橫跨多個 shards，而每個 shard 在搜尋時會使用一個 CPU thread 在處理執行，也就是：&lt;/p></description></item><item><title>Cloudflare 流量處理順序</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211103-cloudflare-waf/</link><pubDate>Wed, 03 Nov 2021 13:11:29 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211103-cloudflare-waf/</guid><description>&lt;h3 id="流量處理順序">流量處理順序&lt;/h3>
&lt;p>應用程式流量在 Cloudflare 邊緣節點會依下列順序處理：&lt;/p>
&lt;ol>
&lt;li>DDoS&lt;/li>
&lt;li>URL 重寫&lt;/li>
&lt;li>頁面規則&lt;/li>
&lt;li>IP 存取規則&lt;/li>
&lt;li>Bot 管理&lt;/li>
&lt;li>防火牆規則&lt;/li>
&lt;li>速率限制&lt;/li>
&lt;li>託管規則&lt;/li>
&lt;li>標頭修改&lt;/li>
&lt;li>存取控制&lt;/li>
&lt;li>Workers&lt;/li>
&lt;/ol></description></item><item><title>Markdown 語法的正則表達式</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211029-regex-for-md/</link><pubDate>Fri, 29 Oct 2021 10:19:41 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211029-regex-for-md/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://chubakbidpaa.com/interesting/2021/09/28/regex-for-md.html" target="_blank" rel="noopener">Markdown 語法的正則表達式&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.markdownguide.org/basic-syntax/" target="_blank" rel="noopener">基本語法&lt;/a>&lt;/li>
&lt;/ul>
&lt;pre tabindex="0">&lt;code># Headings
headerOne = `(#{1}\s)(.*)`
headeTwo = `(#{2}\s)(.*)`
headerThree = `(#{3}\s)(.*)`
headerFour = `(#{4}\s)(.*)`
headerFive = `(#{5}\s)(.*)`
headerSix = `(#{6}\s)(.*)`
# Bold and Italic Text
boldItalicText = `(\*|\_)+(\S+)(\*|\_)+`
# Links
linkText = `(\[.*\])(\((http)(?:s)?(\:\/\/).*\))`
# Images
imageFile = `(\!)(\[(?:.*)?\])(\(.*(\.(jpg|png|gif|tiff|bmp))(?:(\s\&amp;#34;|\&amp;#39;)(\w|\W|\d)+(\&amp;#34;|\&amp;#39;))?\)`
# Unordered List
listText = `(^(\W{1})(\s)(.*)(?:$)?)+`
# Numbered Text
numberedListText = `(^(\d+\.)(\s)(.*)(?:$)?)+`
# Block Quotes
blockQuote = `((^(\&amp;gt;{1})(\s)(.*)(?:$)?)+`
# Inline Code
inlineCode = &amp;#34;(\\`{1})(.*)(\\`{1})&amp;#34;
# Code Block
codeBlock = &amp;#34;(\\`{3}\\n+)(.*)(\\n+\\`{3})&amp;#34;
# Horizontal Line
horizontalLine = `(\=|\-|\*){3}`
# Email Text
emailText = `(\&amp;lt;{1})(\S+@\S+)(\&amp;gt;{1})`
# TABLES
tableText = `(((\|)([a-zA-Z\d+\s#!@&amp;#39;&amp;#34;():;\\\/.\[\]\^&amp;lt;={$}&amp;gt;?(?!-))]+))+(\|))(?:\n)?((\|)(-+))+(\|)(\n)((\|)(\W+|\w+|\S+))+(\|$)`
&lt;/code>&lt;/pre></description></item><item><title>Google Cloud Platform(GCP)：透過 Windows 遠端桌面存取 GCP 執行個體上的 Linux GUI</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211020-google-cloud-platform-gcp-access-linux-server-using-gui-running-in-gcp-instance-using-windows/</link><pubDate>Wed, 20 Oct 2021 16:15:48 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211020-google-cloud-platform-gcp-access-linux-server-using-gui-running-in-gcp-instance-using-windows/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://medium.com/tech-guides/google-cloud-platform-gcp-access-linux-server-using-gui-running-in-gcp-instance-using-windows-201e315925a6" target="_blank" rel="noopener">Google Cloud Platform(GCP)：透過 Windows 遠端桌面存取 GCP 執行個體上的 Linux GUI&lt;/a>&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># This will install GUI and make it as a default startup option and then restart the machine.&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ sudo yum install xrdp tigervnc-server
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>~# sudo su
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>~# passwd
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>~# systemctl enable --now xrdp
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>~# netstat -antup | grep xrdp
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>tcp &lt;span style="color:#ae81ff">0&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span> 0.0.0.0:3389 0.0.0.0:* LISTEN 10202/xrdp
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>tcp &lt;span style="color:#ae81ff">0&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span> 127.0.0.1:3350 0.0.0.0:* LISTEN 10201/xrdp-sesman
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>【筆記】在GCP上建立可Remote dekstop的Ubuntu環境</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211020-gcp-remote-desktop/</link><pubDate>Wed, 20 Oct 2021 16:14:47 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211020-gcp-remote-desktop/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://medium.com/@huiqinng/%E7%AD%86%E8%A8%98-%E5%9C%A8gcp%E4%B8%8A%E5%BB%BA%E7%AB%8B%E5%8F%AFremote-dekstop%E7%9A%84ubuntu%E7%92%B0%E5%A2%83-e56fdbd3a4f2" target="_blank" rel="noopener">【筆記】在 GCP 上建立可 Remote dekstop 的 Ubuntu 環境&lt;/a>&lt;/li>
&lt;/ul>
&lt;h4 id="install">install&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># dependency&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>sudo apt-get install ubuntu-desktop gnome-panel gnome-settings-daemon metacity nautilus gnome-terminal
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># VNC Server&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>sudo apt-get install vnc4server
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 安裝完成後先執行vncserver，會先跳出password設定的選項&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>vncserver
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="modify-vncxstartup">modify &lt;code>~/.vnc/xstartup&lt;/code>&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#!/bin/sh
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Uncomment the following two lines for normal desktop:&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># unset SESSION_MANAGER&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># exec /etc/X11/xinit/xinitrc&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">[&lt;/span> -x /etc/vnc/xstartup &lt;span style="color:#f92672">]&lt;/span> &lt;span style="color:#f92672">&amp;amp;&amp;amp;&lt;/span> exec /etc/vnc/xstartup
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">[&lt;/span> -r $HOME/.Xresources &lt;span style="color:#f92672">]&lt;/span> &lt;span style="color:#f92672">&amp;amp;&amp;amp;&lt;/span> xrdb $HOME/.Xresources
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>xsetroot -solid grey
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>vncconfig -iconic &amp;amp;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>x-terminal-emulator -geometry 80x24+10+10 -ls -title &lt;span style="color:#e6db74">&amp;#34;&lt;/span>$VNCDESKTOP&lt;span style="color:#e6db74"> Desktop&amp;#34;&lt;/span> &amp;amp;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>x-window-manager &amp;amp;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>gnome-panel &amp;amp;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>gnome-settings-daemon &amp;amp;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>metacity &amp;amp;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>nautilus &amp;amp;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="exec">exec&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 殺掉目前執行的vncserver 然後重新執行&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>vncserver -kill :1
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># vncserver預設是執行在port 5900上，如果在後面加上：1 就是5901以此類推&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>vncserver :1
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="設定-reboot-的時候自動執行-vncserver">設定 reboot 的時候自動執行 vncserver&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>@reboot /usr/bin/vncserver :1
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>一次搞懂密碼學中的三兄弟 — Encode、Encrypt 跟 Hash</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211018-what-are-encoding-encrypt-and-hashing/</link><pubDate>Mon, 18 Oct 2021 14:24:01 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211018-what-are-encoding-encrypt-and-hashing/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://medium.com/starbugs/what-are-encoding-encrypt-and-hashing-4b03d40e7b0c" target="_blank" rel="noopener">一次搞懂密碼學中的三兄弟 — Encode、Encrypt 跟 Hash&lt;/a>&lt;/li>
&lt;/ul>
&lt;h3 id="編碼encoding">編碼（Encoding）&lt;/h3>
&lt;blockquote>
&lt;p>不會修改資料、也沒有任何加密的效果，單純就是 換個方式來表達資料 而已，其中最有名的例子就是&lt;code>摩斯密碼&lt;/code>&lt;/p>
&lt;ul>
&lt;li>JavaScript 中有兩個很實用的 function 分別是 &lt;code>encodeURI&lt;/code> 跟 &lt;code>decodeURI&lt;/code> 把網址中的特殊字元（空白、標點符號等等）編碼成符合 URL 的格式&lt;/li>
&lt;li>&lt;code>Base64&lt;/code> 是一種可以把二進位的資料編碼成 ASCII 字元的方法&lt;/li>
&lt;li>&lt;code>霍夫曼編碼（Huffman Coding）&lt;/code> 一種用來進行 無失真壓縮 的編碼演算法，說穿了他的概念就是把常用的字記成縮寫，從而降低資料量、達到壓縮的效果&lt;/li>
&lt;/ul>&lt;/blockquote>
&lt;h3 id="加密encrypt">加密（Encrypt）&lt;/h3>
&lt;blockquote>
&lt;p>加密跟解密必須要有金鑰（Key）才能進行。以最簡單的 凱薩加密法 來說，他加密的方式就是把每個英文字母加上一個 偏移量，這個偏移量就是用來執行加解密的 Key&lt;/p>
&lt;ul>
&lt;li>AES (Advanced Encryption Standard) 是一種對稱加密演算法，所謂的對稱就是說加密解密 都是用同一個 key，這點跟上面說到的凱薩加密法一樣，但 AES 不像凱薩的 key 只有 0-25 這麼少種，而是可以有超過 10³⁸ 種&lt;/li>
&lt;li>RSA 這類非對稱加密法有個很特別的地方，就是他會產生一組兩個 Key 分別叫公鑰（Public Key）跟私鑰（Private Key），而且 用公鑰加密的內容只能用私鑰解&lt;/li>
&lt;/ul>&lt;/blockquote>
&lt;h3 id="雜湊hashing">雜湊（Hashing）&lt;/h3>
&lt;blockquote>
&lt;p>各個 欄位/字元 丟進去某個公式計算的方式就叫做雜湊（Hash），而這個計算公式就稱為 雜湊函數（Hash function），過程可能會做各種加減乘除，最後算出一個值或字串，因為不可能由雜湊後的結果回推，所以雜湊的過程是 不可逆的&lt;/p>&lt;/blockquote></description></item><item><title>Nginx 出現 500 Error 修復 (too many open file, connection)</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211009-nginx-worker-many-file-fix/</link><pubDate>Sat, 09 Oct 2021 11:51:06 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211009-nginx-worker-many-file-fix/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://blog.longwin.com.tw/2011/05/nginx-worker-many-file-fix-2011/" target="_blank" rel="noopener">Nginx 出現 500 Error 修復 (too many open file, connection)&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>Nginx 出現 500 Error, 錯誤訊息只能從 Log 查到, 有遇到下述兩種狀況:&lt;/p>
&lt;h3 id="socket-failed-24-too-many-open-files-while-connecting-to-upstream">socket() failed (24: Too many open files) while connecting to upstream&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>$ sudo su - www-data
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ ulimit -n &lt;span style="color:#75715e"># 看目前系統設定的限制 (ulimit -a # 可查看全部參數)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ae81ff">1024&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># vim /etc/security/limits.conf # 由此檔案設定 nofile (nofile - max number of open files) 的大小&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 增加/修改 下述兩行&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>* soft nofile &lt;span style="color:#ae81ff">655360&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>* hard nofile &lt;span style="color:#ae81ff">655360&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>ulimit -n &lt;span style="color:#75715e"># 登出後, 在登入, 執行就會出現此值&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ae81ff">655360&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 若 ulimit -n 沒出現 655360 的話, 可使用 ulimit -n 655360 # 強制設定&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 再用 ulimit -n 或 ulimit -Sn (驗證軟式設定)、ulimit -Hn (驗證硬式設定) 檢查看看(或 ulimit -a).&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 從系統面另外計算 + 設定&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>lsof | wc -l &lt;span style="color:#75715e"># 計算開啟檔案數量&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>sudo vim /etc/sysctl.conf
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>fs.file-max &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#ae81ff">3268890&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>sudo sysctl -p
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="512-worker_connections-are-not-enough-while-connecting-to-upstream">512 worker_connections are not enough while connecting to upstream&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># /etc/nginx/nginx.conf&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>worker_connections 10240;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 參考 Nginx CoreModule&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># worker_processes 2;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># worker_rlimit_nofile 10240;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># events {&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># # worker_connections 10240;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># }&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Nginx 的 connection 增加後, 整體速度會變慢很多, 主要原因是 php-cgi 不夠用, 所以要作以下調整.&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># php-cgi was started with phpfcgid_children=&amp;#34;10&amp;#34; and phpfcgid_requests=&amp;#34;500&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># ab was run on another server, connect via a switch using GBit ethernet&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># http://till.klampaeckel.de/blog/archives/30-PHP-performance-III-Running-nginx.html&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># vim /etc/nginx/nginx.conf&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>worker_connections 10240;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>worker_rlimit_nofile
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># vim /etc/init.d/php-fcgi&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>PHP_FCGI_CHILDREN&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#ae81ff">15&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>PHP_FCGI_MAX_REQUESTS&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#ae81ff">1000&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>改成
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>PHP_FCGI_CHILDREN&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#ae81ff">512&lt;/span> &lt;span style="color:#75715e"># 或 150 慢慢加, 注意 MySQL connection 是否夠用&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>PHP_FCGI_MAX_REQUESTS&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#ae81ff">10240&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 上述文章的 phpfcgid_stop(), 寫得還不錯, 有需要可以用看看.&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># phpfcgid_stop() {&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># echo &amp;#34;Stopping $name.&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># pids=`pgrep php-cgi`&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># pkill php-cgi&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># wait_for_pids $pids&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># }&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>超簡單！快速打造漂亮又好用的 zsh 終端環境</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211009-zsh/</link><pubDate>Thu, 07 Oct 2021 08:44:18 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211009-zsh/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://medium.com/@white1033/%E8%B6%85%E7%B0%A1%E5%96%AE-%E5%BF%AB%E9%80%9F%E6%89%93%E9%80%A0%E6%BC%82%E4%BA%AE%E5%8F%88%E5%A5%BD%E7%94%A8%E7%9A%84-zsh-%E7%B5%82%E7%AB%AF%E7%92%B0%E5%A2%83-c81874368264" target="_blank" rel="noopener">超簡單！快速打造漂亮又好用的 zsh 終端環境&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://dwye.dev/post/zsh-zim-powerlevel10k/" target="_blank" rel="noopener">用 zsh + zim + powerlevel10k 讓你的 Terminal 潮又快&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://medium.com/starbugs/%E6%89%93%E9%80%A0-10x-engineer-zsh-shell-97e40db76391" target="_blank" rel="noopener">打造 10X Engineer Shell 工作環境&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>利用 GPG 簽署 git commit</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211005-sign_git_commit_with_gpg/</link><pubDate>Tue, 05 Oct 2021 18:28:06 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20211005-sign_git_commit_with_gpg/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://blog.puckwang.com/posts/2019/sign_git_commit_with_gpg/" target="_blank" rel="noopener">利用 GPG 簽署 git commit&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Gitlab-CI Introduction</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210924-gitlab/</link><pubDate>Fri, 24 Sep 2021 11:11:03 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210924-gitlab/</guid><description>&lt;h1 id="gitlab-ci">Gitlab CI&lt;/h1>
&lt;h2 id="concept">Concept&lt;/h2>
&lt;h3 id="gitlab">Gitlab&lt;/h3>
&lt;ul>
&lt;li>DevOps&lt;/li>
&lt;li>GitOps&lt;/li>
&lt;/ul>
&lt;h3 id="workflow">Workflow&lt;/h3>
&lt;pre tabindex="0">&lt;code>code push -&amp;gt; pipeline -&amp;gt; stage -&amp;gt; job
&lt;/code>&lt;/pre>&lt;h3 id="design">Design&lt;/h3>
&lt;pre tabindex="0">&lt;code>plan -&amp;gt; code -&amp;gt; build -&amp;gt; test -&amp;gt; release -&amp;gt; deploy -&amp;gt; operate -&amp;gt; monitor -&amp;gt; plan
&lt;/code>&lt;/pre>&lt;h3 id="runner-executors">Runner Executors&lt;/h3>
&lt;ul>
&lt;li>Shell&lt;/li>
&lt;li>VirtualBox&lt;/li>
&lt;li>Docker&lt;/li>
&lt;li>Docker Machine&lt;/li>
&lt;li>Kubernetes&lt;/li>
&lt;li>Else&amp;hellip;&lt;/li>
&lt;/ul>
&lt;h3 id="references">References&lt;/h3>
&lt;ul>
&lt;li>&lt;a href="https://docs.gitlab.com/ee/ci/" target="_blank" rel="noopener">Gitlab CI/CD&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://docs.gitlab.com/runner/" target="_blank" rel="noopener">Gitlab Runner&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://docs.gitlab.com/ee/ci/yaml/" target="_blank" rel="noopener">.gitlab-ci.yaml&lt;/a>&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="runner">Runner&lt;/h2>
&lt;h3 id="register">Register&lt;/h3>
&lt;p>&lt;code>gitlab-runner register&lt;/code>&lt;/p>
&lt;h3 id="after-register">After register&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-toml" data-lang="toml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">concurrent&lt;/span> = &lt;span style="color:#ae81ff">1&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">check_interval&lt;/span> = &lt;span style="color:#ae81ff">0&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>[&lt;span style="color:#a6e22e">session_server&lt;/span>]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">session_timeout&lt;/span> = &lt;span style="color:#ae81ff">1800&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>[[&lt;span style="color:#a6e22e">runners&lt;/span>]]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">name&lt;/span> = &lt;span style="color:#e6db74">&amp;#34;public-shell&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">url&lt;/span> = &lt;span style="color:#e6db74">&amp;#34;https://gitlab.go2cloudten.com/&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">token&lt;/span> = &lt;span style="color:#e6db74">&amp;#34;-mdH9OAOzG5yPsf_AVnW&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">executor&lt;/span> = &lt;span style="color:#e6db74">&amp;#34;shell&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>[[&lt;span style="color:#a6e22e">runners&lt;/span>]]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">name&lt;/span> = &lt;span style="color:#e6db74">&amp;#34;public-docker&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">url&lt;/span> = &lt;span style="color:#e6db74">&amp;#34;https://gitlab.go2cloudten.com/&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">token&lt;/span> = &lt;span style="color:#e6db74">&amp;#34;AcEGPPKTS1uuQ_A_qpWy&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">executor&lt;/span> = &lt;span style="color:#e6db74">&amp;#34;docker&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> [&lt;span style="color:#a6e22e">runners&lt;/span>.&lt;span style="color:#a6e22e">docker&lt;/span>]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">dns&lt;/span> = [&lt;span style="color:#e6db74">&amp;#34;192.168.185.5&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;192.168.185.6&amp;#34;&lt;/span>]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">tls_verify&lt;/span> = &lt;span style="color:#66d9ef">false&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">image&lt;/span> = &lt;span style="color:#e6db74">&amp;#34;registry.go2cloudten.com/it/office_sop/node:12.13.0&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">privileged&lt;/span> = &lt;span style="color:#66d9ef">true&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">disable_entrypoint_overwrite&lt;/span> = &lt;span style="color:#66d9ef">false&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">oom_kill_disable&lt;/span> = &lt;span style="color:#66d9ef">false&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">disable_cache&lt;/span> = &lt;span style="color:#66d9ef">false&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">shm_size&lt;/span> = &lt;span style="color:#ae81ff">0&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">pull_policy&lt;/span> = &lt;span style="color:#e6db74">&amp;#34;if-not-present&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">volumes&lt;/span> = [&lt;span style="color:#e6db74">&amp;#34;/cache&amp;#34;&lt;/span>]
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;hr>
&lt;h2 id="repository">Repository&lt;/h2>
&lt;h3 id="gitlab-ciyaml">.gitlab-ci.yaml&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">stages&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">domain&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">check-icp&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">stage&lt;/span>: &lt;span style="color:#ae81ff">domain&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">image&lt;/span>: &lt;span style="color:#ae81ff">registry.go2cloudten.com/it/office_sop/icp&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">tags&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">docker&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">script&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">domains=$(awk -F &amp;#39;|&amp;#39; &amp;#39;{if($6 ~ &amp;#34;Y&amp;#34; &amp;amp;&amp;amp; ($7 ~ &amp;#34;West&amp;#34; || $7 ~ &amp;#34;Yuqu&amp;#34;)) print $3}&amp;#39; domains-info.md | sed &amp;#39;s/ //g&amp;#39; | sort | uniq)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">if [[ &amp;#34;${domains}&amp;#34; == &amp;#34;&amp;#34; ]]; then telegram.sh &amp;#39;There is no domain in list&amp;#39; ; else telegram.sh &amp;#39;Start checking ICP.&amp;#39; ; fi&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">for i in ${domains}; do result=$(checkicp ${i}); if [[ &amp;#34;${result}&amp;#34; == &amp;#34;未备案&amp;#34; ]];then telegram.sh &amp;#34;${i} 未备案&amp;#34;; sleep 1 ;fi;done&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">telegram.sh &amp;#39;ICP check completed.&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">only&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">schedules&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>SHELL编程之常用技巧</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210922-shellbian-cheng-zhi-chang-yong-ji-qiao/</link><pubDate>Wed, 22 Sep 2021 13:01:11 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210922-shellbian-cheng-zhi-chang-yong-ji-qiao/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://zorrozou.github.io/docs/books/shellbian-cheng-zhi-chang-yong-ji-qiao.html" target="_blank" rel="noopener">SHELL 编程之常用技巧&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://zorrozou.github.io/docs/books/shellbian-cheng-zhi-nei-jian-ming-ling.html" target="_blank" rel="noopener">SHELL 编程之内建命令&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://zorrozou.github.io/docs/books/shellbian-cheng-zhi-te-shu-fu-hao.html" target="_blank" rel="noopener">SHELL 编程之特殊符号&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Docker Introduction</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210917-docker/</link><pubDate>Fri, 17 Sep 2021 14:11:03 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210917-docker/</guid><description>&lt;h1 id="docker">Docker&lt;/h1>
&lt;h2 id="concept">Concept&lt;/h2>
&lt;h3 id="vm-vs-container">VM vs Container&lt;/h3>
&lt;ul>
&lt;li>VM - Base on OS&lt;/li>
&lt;li>Container - Base on Application (Linux Kernel: Namespace and Cgroup)&lt;/li>
&lt;/ul>
&lt;h3 id="client-to-server">Client to Server&lt;/h3>
&lt;ul>
&lt;li>Docker daemon - containerd, docker-containerd-shim, docker-runc&lt;/li>
&lt;li>Docker client - cli command&lt;/li>
&lt;/ul>
&lt;pre tabindex="0">&lt;code>docker cli -&amp;gt; docker daemon -&amp;gt; containerd -&amp;gt; runc -&amp;gt; namespace &amp;amp; cgroup
&lt;/code>&lt;/pre>&lt;h3 id="image">Image&lt;/h3>
&lt;ul>
&lt;li>Snapshots&lt;/li>
&lt;/ul>
&lt;h3 id="container">Container&lt;/h3>
&lt;ul>
&lt;li>Read-Only processes on image&lt;/li>
&lt;/ul>
&lt;h3 id="hub--registry">Hub / Registry&lt;/h3>
&lt;ul>
&lt;li>Store images&lt;/li>
&lt;/ul>
&lt;h3 id="references">References&lt;/h3>
&lt;ul>
&lt;li>&lt;a href="https://philipzheng.gitbook.io/docker_practice/" target="_blank" rel="noopener">Docker —— 從入門到實踐&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://docs.docker.com/" target="_blank" rel="noopener">docker docs&lt;/a>&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="docker-commands">Docker commands&lt;/h2>
&lt;h3 id="dockerfile">Dockerfile&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-dockerfile" data-lang="dockerfile">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">ARG&lt;/span> dist&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;/tmp/password&amp;#34;&lt;/span>&lt;span style="color:#960050;background-color:#1e0010">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#960050;background-color:#1e0010">&lt;/span>&lt;span style="color:#66d9ef">ARG&lt;/span> projectDir&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;/password&amp;#34;&lt;/span>&lt;span style="color:#960050;background-color:#1e0010">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#960050;background-color:#1e0010">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#960050;background-color:#1e0010">&lt;/span>&lt;span style="color:#66d9ef">FROM&lt;/span>&lt;span style="color:#e6db74"> golang:1.16-alpine3.14 AS builder&lt;/span>&lt;span style="color:#960050;background-color:#1e0010">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#960050;background-color:#1e0010">&lt;/span>&lt;span style="color:#66d9ef">RUN&lt;/span> apk add build-base upx&lt;span style="color:#960050;background-color:#1e0010">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#960050;background-color:#1e0010">&lt;/span>&lt;span style="color:#66d9ef">ARG&lt;/span> dist&lt;span style="color:#960050;background-color:#1e0010">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#960050;background-color:#1e0010">&lt;/span>&lt;span style="color:#66d9ef">ARG&lt;/span> projectDir&lt;span style="color:#960050;background-color:#1e0010">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#960050;background-color:#1e0010">&lt;/span>&lt;span style="color:#66d9ef">WORKDIR&lt;/span>&lt;span style="color:#e6db74"> ${projectDir}&lt;/span>&lt;span style="color:#960050;background-color:#1e0010">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#960050;background-color:#1e0010">&lt;/span>&lt;span style="color:#66d9ef">COPY&lt;/span> . .&lt;span style="color:#960050;background-color:#1e0010">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#960050;background-color:#1e0010">&lt;/span>&lt;span style="color:#66d9ef">RUN&lt;/span> go build -trimpath -o main cmd/main.go&lt;span style="color:#960050;background-color:#1e0010">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#960050;background-color:#1e0010">&lt;/span>&lt;span style="color:#66d9ef">RUN&lt;/span> upx -9 -o &lt;span style="color:#e6db74">${&lt;/span>dist&lt;span style="color:#e6db74">}&lt;/span> main&lt;span style="color:#960050;background-color:#1e0010">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#960050;background-color:#1e0010">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#960050;background-color:#1e0010">&lt;/span>&lt;span style="color:#66d9ef">FROM&lt;/span>&lt;span style="color:#e6db74"> scratch&lt;/span>&lt;span style="color:#960050;background-color:#1e0010">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#960050;background-color:#1e0010">&lt;/span>&lt;span style="color:#66d9ef">ARG&lt;/span> dist&lt;span style="color:#960050;background-color:#1e0010">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#960050;background-color:#1e0010">&lt;/span>&lt;span style="color:#66d9ef">ENV&lt;/span> TZ&lt;span style="color:#f92672">=&lt;/span>Asia/Taipei&lt;span style="color:#960050;background-color:#1e0010">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#960050;background-color:#1e0010">&lt;/span>&lt;span style="color:#66d9ef">COPY&lt;/span> --from&lt;span style="color:#f92672">=&lt;/span>builder &lt;span style="color:#e6db74">${&lt;/span>dist&lt;span style="color:#e6db74">}&lt;/span> /usr/local/bin/password&lt;span style="color:#960050;background-color:#1e0010">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="dockerfile1">Dockerfile1&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-dockerfile" data-lang="dockerfile">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">FROM&lt;/span>&lt;span style="color:#e6db74"> alpine&lt;/span>&lt;span style="color:#960050;background-color:#1e0010">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#960050;background-color:#1e0010">&lt;/span>&lt;span style="color:#66d9ef">CMD&lt;/span> [&lt;span style="color:#e6db74">&amp;#34;nc&amp;#34;&lt;/span>,&lt;span style="color:#e6db74">&amp;#34;-l&amp;#34;&lt;/span>,&lt;span style="color:#e6db74">&amp;#34;12345&amp;#34;&lt;/span>]&lt;span style="color:#960050;background-color:#1e0010">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="dockerfile2">Dockerfile2&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-dockerfile" data-lang="dockerfile">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">FROM&lt;/span>&lt;span style="color:#e6db74"> alpine&lt;/span>&lt;span style="color:#960050;background-color:#1e0010">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#960050;background-color:#1e0010">&lt;/span>&lt;span style="color:#66d9ef">CMD&lt;/span> [&lt;span style="color:#e6db74">&amp;#34;echo&amp;#34;&lt;/span>,&lt;span style="color:#e6db74">&amp;#34;DOCKER&amp;#34;&lt;/span>]&lt;span style="color:#960050;background-color:#1e0010">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="docker-build-command">docker build command&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>docker build . -t program
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>docker build . -f Dockerfile -t test_mysql
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>docker build . -t hello:v1.1 --build-arg dist&lt;span style="color:#f92672">=&lt;/span>/tmp/hello --build-arg projectDir&lt;span style="color:#f92672">=&lt;/span>/hello
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;hr>
&lt;h3 id="docker-build">docker build&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>. docker/status
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>echo -e &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>GREEN&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">Before build&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>RESET&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>docker image ls
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>docker build . -f docker/Dockerfile1 -t test1
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>docker build . -f docker/Dockerfile2 -t test2
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="docker-image">docker image&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>. docker/status
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>echo -e &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>GREEN&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">After build&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>RESET&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>docker image ls
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;hr>
&lt;h3 id="docker-run-and-rm">docker run AND rm&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>. docker/status
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>echo -e &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>GREEN&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">Run container1&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>RESET&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>docker run -d --name container1 test1
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>echo -e &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>GREEN&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">Run container2&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>RESET&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>docker run -d --name container2 test2
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>echo -e &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>GREEN&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">List alive containers&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>RESET&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>docker ps
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>echo -e &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>GREEN&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">List all containers&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>RESET&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>docker ps -a
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>echo -e &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>GREEN&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">Remove alive container&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>RESET&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>docker rm -f container1
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>echo -e &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>GREEN&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">List all containers&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>RESET&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>docker ps -a
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>echo -e &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>GREEN&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">Remove exit container&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>RESET&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>docker rm container2
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>echo -e &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>GREEN&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">List all containers&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>RESET&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>docker ps -a
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;hr>
&lt;h3 id="docker-pull-and-rmi">docker pull AND rmi&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>. docker/status
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>echo -e &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>GREEN&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">List all image&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>RESET&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>docker image ls
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>echo -e &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>GREEN&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">Pull alpine image&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>RESET&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>docker pull alpine
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>echo -e &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>GREEN&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">List all image&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>RESET&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>docker image ls
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;hr>
&lt;h3 id="docker-rmi">docker rmi&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>. docker/status
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>echo -e &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>GREEN&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">Remove alpine image&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>RESET&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>docker rmi alpine
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>echo -e &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>GREEN&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">List all image&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>RESET&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>docker image ls
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;hr>
&lt;h3 id="prune">prune&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>docker system prune -f --volumes
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;hr>
&lt;h3 id="docker-history">docker history&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>. docker/status
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>echo -e &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>GREEN&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">History of test1&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>RESET&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>docker history test1
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>echo -e &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>GREEN&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">History of mysql:8&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>RESET&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>docker history mysql:8
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;hr>
&lt;h2 id="docker-remote">Docker remote&lt;/h2>
&lt;h3 id="edit-service-file">Edit service file&lt;/h3>
&lt;pre tabindex="0">&lt;code># /lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -H tcp://0.0.0.0:2375
&lt;/code>&lt;/pre>&lt;h3 id="restart-service">Restart service&lt;/h3>
&lt;pre tabindex="0">&lt;code>systemctl daemon-reload
systemctl restart docker
&lt;/code>&lt;/pre>&lt;h3 id="specify-docker_host">Specify DOCKER_HOST&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>. docker/status
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>echo -e &lt;span style="color:#e6db74">&amp;#34;&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>GREEN&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">List images on 192.168.185.9&lt;/span>&lt;span style="color:#e6db74">${&lt;/span>RESET&lt;span style="color:#e6db74">}&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>DOCKER_HOST&lt;span style="color:#f92672">=&lt;/span>192.168.185.9:2375 docker images
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;hr>
&lt;h2 id="docker-compose">Docker-compose&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">version&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;3&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">services&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">svn&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">image&lt;/span>: &lt;span style="color:#ae81ff">zeyanlin/svn&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">environment&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">LDAP_HOSTS=${LDAP_HOSTS}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">LDAP_BASE_DN=${LDAP_BASE_DN}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">LDAP_BIND_DN=${LDAP_BIND_DN}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">LDAP_ADMIN_PASS=${LDAP_ADMIN_PASS}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">ports&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">8000&lt;/span>:&lt;span style="color:#ae81ff">80&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">3690&lt;/span>:&lt;span style="color:#ae81ff">3690&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">depends_on&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">ldap&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">ldap&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">image&lt;/span>: &lt;span style="color:#ae81ff">zeyanlin/openldap&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">environment&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">LDAP_DOMAIN=${LDAP_DOMAIN}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">LDAP_ADMIN_PASS=${LDAP_ADMIN_PASS}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">ports&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">389&lt;/span>:&lt;span style="color:#ae81ff">389&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">636&lt;/span>:&lt;span style="color:#ae81ff">636&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">php&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">image&lt;/span>: &lt;span style="color:#ae81ff">zeyanlin/phpldapadmin&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">environment&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">LDAP_HOSTS=${LDAP_HOSTS}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">ports&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">80&lt;/span>:&lt;span style="color:#ae81ff">80&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">depends_on&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">ldap&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;hr>
&lt;h3 id="env">Env&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-ini" data-lang="ini">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">LDAP_HOSTS&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">ldap&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">LDAP_DOMAIN&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;knowhow.fun&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">LDAP_BASE_DN&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;dc=knowhow,dc=fun&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">LDAP_BIND_DN&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;cn=admin&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">LDAP_ADMIN_PASS&lt;/span>&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;123qwe&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Golang基准测试</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210902-golang-ji-zhun-ce-shi/</link><pubDate>Thu, 02 Sep 2021 12:50:33 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210902-golang-ji-zhun-ce-shi/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://mp.weixin.qq.com/s?__biz=MzkxNzAzNDA3Ng==&amp;amp;mid=2247485595&amp;amp;idx=1&amp;amp;sn=9981e6103a6b33cc3a06be0781a2bf10&amp;amp;chksm=c1478da8f63004be44a8c84941280f3888d4e5a2120a4288ed1a21f8a1a82fe65d719c31bae6#rd" target="_blank" rel="noopener">Golang 基准测试&lt;/a>&lt;/li>
&lt;/ul>
&lt;h4 id="基本使用">基本使用&lt;/h4>
&lt;blockquote>
&lt;p>基准测试常用于代码性能测试，函数需要导入 testing 包，并定义以 Benchmark 开头的函数， 参数为 testing.B 指针类型，在测试函数中循环调用函数多次&lt;/p>&lt;/blockquote>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>➜ go test -bench&lt;span style="color:#f92672">=&lt;/span>. -run&lt;span style="color:#f92672">=&lt;/span>none
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>goos: darwin
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>goarch: amd64
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>pkg: pkg06
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>cpu: Intel&lt;span style="color:#f92672">(&lt;/span>R&lt;span style="color:#f92672">)&lt;/span> Core&lt;span style="color:#f92672">(&lt;/span>TM&lt;span style="color:#f92672">)&lt;/span> i7-8850H CPU @ 2.60GHz
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>BenchmarkFib-12 &lt;span style="color:#ae81ff">250&lt;/span> &lt;span style="color:#ae81ff">4682682&lt;/span> ns/op
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>PASS
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>ok pkg06 1.875s
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>➜ go test -bench&lt;span style="color:#f92672">=&lt;/span>. -benchmem -run&lt;span style="color:#f92672">=&lt;/span>none
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>goos: darwin
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>goarch: amd64
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>pkg: pkg06
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>cpu: Intel&lt;span style="color:#f92672">(&lt;/span>R&lt;span style="color:#f92672">)&lt;/span> Core&lt;span style="color:#f92672">(&lt;/span>TM&lt;span style="color:#f92672">)&lt;/span> i7-8850H CPU @ 2.60GHz
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>BenchmarkFib-12 &lt;span style="color:#ae81ff">249&lt;/span> &lt;span style="color:#ae81ff">4686452&lt;/span> ns/op &lt;span style="color:#ae81ff">0&lt;/span> B/op &lt;span style="color:#ae81ff">0&lt;/span> allocs/op
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>PASS
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>ok pkg06 1.854s
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="bench-的工作原理">bench 的工作原理&lt;/h4>
&lt;ul>
&lt;li>基准测试函数会被一直调用直到 &lt;code>b.N&lt;/code> 无效，它是基准测试循环的次数&lt;/li>
&lt;li>&lt;code>b.N&lt;/code> 从 &lt;code>1&lt;/code> 开始，如果基准测试函数在 &lt;code>1&lt;/code> 秒内就完成 (默认值)，则 &lt;code>b.N&lt;/code> 增加，并再次运行基准测试函数&lt;/li>
&lt;li>&lt;code>b.N&lt;/code> 的值会按照序列 &lt;code>1,2,5,10,20,50,...&lt;/code> 增加，同时再次运行基准测测试函数&lt;/li>
&lt;li>上述结果解读代表 &lt;code>1&lt;/code> 秒内运行了 &lt;code>250&lt;/code> 次，每次 &lt;code>4682682 ns&lt;/code>&lt;/li>
&lt;li>&lt;code>-12&lt;/code> 后缀和用于运行次测试的 &lt;code>GOMAXPROCS&lt;/code> 值有关。与 &lt;code>GOMAXPROCS&lt;/code> 一样，此数字默认为启动时 Go 进程可见的 CPU 数。可以使用 &lt;code>-cpu&lt;/code> 标识更改此值，可以传入多个值以列表形式来运行基准测试&lt;/li>
&lt;/ul>
&lt;h4 id="传入-cpu-num-进行测试">传入 cpu num 进行测试&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>➜ go test -bench&lt;span style="color:#f92672">=&lt;/span>. -cpu&lt;span style="color:#f92672">=&lt;/span>1,2,4 -benchmem -run&lt;span style="color:#f92672">=&lt;/span>none
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>goos: darwin
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>goarch: amd64
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>pkg: pkg06
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>cpu: Intel&lt;span style="color:#f92672">(&lt;/span>R&lt;span style="color:#f92672">)&lt;/span> Core&lt;span style="color:#f92672">(&lt;/span>TM&lt;span style="color:#f92672">)&lt;/span> i7-8850H CPU @ 2.60GHz
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>BenchmarkFib &lt;span style="color:#ae81ff">244&lt;/span> &lt;span style="color:#ae81ff">4694667&lt;/span> ns/op &lt;span style="color:#ae81ff">0&lt;/span> B/op &lt;span style="color:#ae81ff">0&lt;/span> allocs/op
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>BenchmarkFib-2 &lt;span style="color:#ae81ff">255&lt;/span> &lt;span style="color:#ae81ff">4721201&lt;/span> ns/op &lt;span style="color:#ae81ff">0&lt;/span> B/op &lt;span style="color:#ae81ff">0&lt;/span> allocs/op
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>BenchmarkFib-4 &lt;span style="color:#ae81ff">256&lt;/span> &lt;span style="color:#ae81ff">4756392&lt;/span> ns/op &lt;span style="color:#ae81ff">0&lt;/span> B/op &lt;span style="color:#ae81ff">0&lt;/span> allocs/op
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>PASS
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>ok pkg06 5.826s
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="count-多次运行基准测试">count 多次运行基准测试&lt;/h4>
&lt;blockquote>
&lt;p>因为热缩放、内存局部性、后台处理、gc 活动等等会导致单次的误差，所以一般会进行多次测试&lt;/p></description></item><item><title>使用mydumper备份数据库</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210901-mydumper/</link><pubDate>Wed, 01 Sep 2021 17:58:48 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210901-mydumper/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://www.bboy.app/2021/08/09/%E4%BD%BF%E7%94%A8mydumper%E5%A4%87%E4%BB%BD%E6%95%B0%E6%8D%AE%E5%BA%93/" target="_blank" rel="noopener">使用 mydumper 备份数据库&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://github.com/mydumper/mydumper" target="_blank" rel="noopener">MyDumper&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Docker 安全最佳實務：速查表</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210820-how-to-improve-your-docker-containers-security-cheat-sheet/</link><pubDate>Fri, 20 Aug 2021 23:14:30 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210820-how-to-improve-your-docker-containers-security-cheat-sheet/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://blog.gitguardian.com/how-to-improve-your-docker-containers-security-cheat-sheet/" target="_blank" rel="noopener">Docker 安全最佳實務：速查表&lt;/a>&lt;/li>
&lt;/ul>
&lt;h3 id="映像安全">映像安全&lt;/h3>
&lt;h4 id="使用可信任的映像">使用可信任的映像&lt;/h4>
&lt;h4 id="非特權使用者">非特權使用者&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-dockerfile" data-lang="dockerfile">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">FROM&lt;/span>&lt;span style="color:#e6db74"> base_image&lt;/span>&lt;span style="color:#960050;background-color:#1e0010">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#960050;background-color:#1e0010">&lt;/span>&lt;span style="color:#66d9ef">RUN&lt;/span> addgroup -S appgroup &lt;span style="color:#f92672">&amp;amp;&amp;amp;&lt;/span> adduser -S appuser -G appgroup&lt;span style="color:#960050;background-color:#1e0010">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#960050;background-color:#1e0010">&lt;/span>&lt;span style="color:#66d9ef">USER&lt;/span>&lt;span style="color:#e6db74"> appuser&lt;/span>&lt;span style="color:#960050;background-color:#1e0010">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="user-id-命名空間">User ID 命名空間&lt;/h4>
&lt;blockquote>
&lt;p>隔離命名空間，避免容器權限提升影響主機。&lt;/p>&lt;/blockquote>
&lt;p>為了降低風險，請在主機與 Docker daemon 上使用 &lt;code>--userns-remap&lt;/code> 選項設定獨立的命名空間。&lt;/p>
&lt;h3 id="容器執行期安全">容器執行期安全&lt;/h3>
&lt;h4 id="禁止新增權限">禁止新增權限&lt;/h4>
&lt;p>為了提升安全性，建議在建立容器後明確禁止新增權限：&lt;code>--security-opt=no-new-privileges&lt;/code>。&lt;/p>
&lt;h4 id="定義細粒度能力">定義細粒度能力&lt;/h4>
&lt;p>例如，Web 伺服器可能只需要 &lt;code>NET_BIND_SERVICE&lt;/code> 來綁定 80 連接埠。&lt;/p>
&lt;h4 id="控制資源使用">控制資源使用&lt;/h4>
&lt;p>&lt;code>docker run --memory=&amp;quot;400m&amp;quot; --cpus=&amp;quot;0.5&amp;quot; &lt;/code>&lt;/p>
&lt;h3 id="主機系統安全">主機系統安全&lt;/h3>
&lt;h4 id="敏感檔案系統區域">敏感檔案系統區域&lt;/h4>
&lt;p>若需要存取主機設備，請謹慎以 &lt;code>[r|w|m]&lt;/code> 旗標（&lt;code>read&lt;/code>、&lt;code>write&lt;/code>、&lt;code>mknod&lt;/code>）開啟必要權限。&lt;/p>
&lt;h4 id="容器檔案系統存取">容器檔案系統存取&lt;/h4>
&lt;p>&lt;code>docker run --read-only --tmpfs /tmp:rw ,noexec,nosuid &lt;/code>&lt;/p>
&lt;h4 id="持久化儲存">持久化儲存&lt;/h4>
&lt;p>如果需要和主機檔案系統或其他容器共享資料，有兩種做法：&lt;/p>
&lt;ul>
&lt;li>使用可限制磁碟空間的 bind mount（&lt;code>--mount type=bind,o=size&lt;/code>）&lt;/li>
&lt;li>為專用分割區建立 bind volume（&lt;code>--mount type=volume&lt;/code>）&lt;/li>
&lt;/ul>
&lt;h3 id="網路安全">網路安全&lt;/h3>
&lt;h4 id="docker-daemon-socket">Docker daemon socket&lt;/h4>
&lt;p>Docker 使用的 UNIX socket 不應暴露：&lt;code>/var/run/docker.sock&lt;/code>&lt;/p></description></item><item><title>[译] Go语言inline内联的策略与限制</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210814-go-inlining-strategy-limitation/</link><pubDate>Sat, 14 Aug 2021 20:33:41 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210814-go-inlining-strategy-limitation/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://www.pengrl.com/p/20028/" target="_blank" rel="noopener">[译] Go 语言 inline 内联的策略与限制&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://medium.com/a-journey-with-go/go-inlining-strategy-limitation-6b6d7fc3b1be" target="_blank" rel="noopener">Go: Inlining Strategy &amp;amp; Limitation&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://deepu.tech/memory-management-in-golang/" target="_blank" rel="noopener">Visualizing memory management in Golang&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://medium.com/eureka-engineering/understanding-allocations-in-go-stack-heap-memory-9a2631b5035d" target="_blank" rel="noopener">Understanding Allocations in Go&lt;/a>&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">package&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> &lt;span style="color:#e6db74">&amp;#34;fmt&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">func&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">n&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> []&lt;span style="color:#66d9ef">float32&lt;/span>{&lt;span style="color:#ae81ff">120.4&lt;/span>, &lt;span style="color:#f92672">-&lt;/span>&lt;span style="color:#ae81ff">46.7&lt;/span>, &lt;span style="color:#ae81ff">32.50&lt;/span>, &lt;span style="color:#ae81ff">34.65&lt;/span>, &lt;span style="color:#f92672">-&lt;/span>&lt;span style="color:#ae81ff">67.45&lt;/span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">fmt&lt;/span>.&lt;span style="color:#a6e22e">Printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;The total is %.02f\n&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">sum&lt;/span>(&lt;span style="color:#a6e22e">n&lt;/span>))
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">func&lt;/span> &lt;span style="color:#a6e22e">sum&lt;/span>(&lt;span style="color:#a6e22e">s&lt;/span> []&lt;span style="color:#66d9ef">float32&lt;/span>) &lt;span style="color:#66d9ef">float32&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">var&lt;/span> &lt;span style="color:#a6e22e">t&lt;/span> &lt;span style="color:#66d9ef">float32&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">for&lt;/span> &lt;span style="color:#a6e22e">_&lt;/span>, &lt;span style="color:#a6e22e">v&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#66d9ef">range&lt;/span> &lt;span style="color:#a6e22e">s&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">t&lt;/span> &amp;lt; &lt;span style="color:#ae81ff">0&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">t&lt;/span> = &lt;span style="color:#a6e22e">add&lt;/span>(&lt;span style="color:#a6e22e">t&lt;/span>, &lt;span style="color:#a6e22e">v&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> } &lt;span style="color:#66d9ef">else&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">t&lt;/span> = &lt;span style="color:#a6e22e">sub&lt;/span>(&lt;span style="color:#a6e22e">t&lt;/span>, &lt;span style="color:#a6e22e">v&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#a6e22e">t&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">func&lt;/span> &lt;span style="color:#a6e22e">add&lt;/span>(&lt;span style="color:#a6e22e">a&lt;/span>, &lt;span style="color:#a6e22e">b&lt;/span> &lt;span style="color:#66d9ef">float32&lt;/span>) &lt;span style="color:#66d9ef">float32&lt;/span> { &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#a6e22e">a&lt;/span> &lt;span style="color:#f92672">+&lt;/span> &lt;span style="color:#a6e22e">b&lt;/span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">func&lt;/span> &lt;span style="color:#a6e22e">sub&lt;/span>(&lt;span style="color:#a6e22e">a&lt;/span>, &lt;span style="color:#a6e22e">b&lt;/span> &lt;span style="color:#66d9ef">float32&lt;/span>) &lt;span style="color:#66d9ef">float32&lt;/span> { &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#a6e22e">a&lt;/span> &lt;span style="color:#f92672">-&lt;/span> &lt;span style="color:#a6e22e">b&lt;/span> }
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>使用参数&lt;code>-gflags=&amp;quot;-m&amp;quot;&lt;/code>运行，可显示被内联的函数&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>./op.go:3:6: can inline add
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>./op.go:7:6: can inline sub
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>./main.go:16:11: inlining call to sub
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>./main.go:14:11: inlining call to add
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>./main.go:7:12: inlining call to fmt.Printf
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>可以看到 add 方法被内联了。但是，为什么 sum 方法没有被内联呢？使用运行参数&lt;code>-gflags=&amp;quot;-m -m&amp;quot;&lt;/code>可以看到原因：&lt;/p></description></item><item><title>SQL Join 類型視覺化解說</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210813-sql-join-types-explained-visually/</link><pubDate>Fri, 13 Aug 2021 16:16:54 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210813-sql-join-types-explained-visually/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://dataschool.com/how-to-teach-people-sql/sql-join-types-explained-visually/" target="_blank" rel="noopener">SQL Join 類型視覺化解說&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Git 小技巧：用 .mailmap 合併不同作者</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210805-little-git-tricks-use-mailmap-to-merge-different-authors/</link><pubDate>Thu, 05 Aug 2021 13:42:14 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210805-little-git-tricks-use-mailmap-to-merge-different-authors/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://improveandrepeat.com/2019/06/little-git-tricks-use-mailmap-to-merge-different-authors/" target="_blank" rel="noopener">Git 小技巧：用 .mailmap 合併不同作者&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>&lt;code>.mailmap&lt;/code> 檔案 ==&amp;gt; &lt;code>Name you want to keep &amp;lt;email&amp;gt; Name you no longer want &amp;lt;email&amp;gt;&lt;/code>&lt;/p>
&lt;pre tabindex="0">&lt;code>John Doe John Doe
John Doe John Doe
John Doe john doe
Max Example Max
&lt;/code>&lt;/pre>&lt;h5 id="之前">之前&lt;/h5>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>$ git shortlog -se
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ae81ff">1&lt;/span> John Doe &amp;lt;John@Doe.org&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ae81ff">1&lt;/span> John Doe &amp;lt;John@doe.org&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ae81ff">2&lt;/span> John Doe &amp;lt;john@doe.org&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ae81ff">1&lt;/span> Max &amp;lt;max@test.co.uk&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ae81ff">3&lt;/span> Max Example &amp;lt;hi@test.com&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ae81ff">1&lt;/span> john doe &amp;lt;john@doe.org&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h5 id="之後">之後&lt;/h5>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>$ git shortlog -se
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ae81ff">5&lt;/span> John Doe &amp;lt;john@doe.org&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#ae81ff">4&lt;/span> Max Example &amp;lt;hi@test.com&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>Go Modules 處理 Private GIT Repository 流程</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210723-read-private-module-in-golang/</link><pubDate>Fri, 23 Jul 2021 09:40:39 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210723-read-private-module-in-golang/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://blog.wu-boy.com/2020/03/read-private-module-in-golang/" target="_blank" rel="noopener">Go Modules 處理 Private GIT Repository 流程&lt;/a>&lt;/li>
&lt;/ul>
&lt;ol>
&lt;li>&lt;code>go env -w GOPRIVATE=github.com/appleboy&lt;/code>
&lt;ol>
&lt;li>&lt;code>go env -w GONOPROXY=github.com/appleboy&lt;/code>&lt;/li>
&lt;li>&lt;code>go env -w GONOSUMDB=github.com/appleboy&lt;/code>&lt;/li>
&lt;/ol>
&lt;/li>
&lt;li>&lt;code>git config --global url.&amp;quot;https://$USERNAME:$ACCESS_TOKEN@github.com&amp;quot;.insteadOf &amp;quot;https://github.com&amp;quot;&lt;/code>
&lt;ol>
&lt;li>&lt;code>git config --global url.ssh://git@your.private.git/.insteadOf https://your.private.git/&lt;/code>&lt;/li>
&lt;/ol>
&lt;/li>
&lt;/ol></description></item><item><title>Gin中文文档</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210722-shuangdeyu-gin-book/</link><pubDate>Thu, 22 Jul 2021 15:55:48 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210722-shuangdeyu-gin-book/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://www.kancloud.cn/shuangdeyu/gin_book/949450" target="_blank" rel="noopener">自定义路由日志的格式&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.kancloud.cn/shuangdeyu/gin_book/949444" target="_blank" rel="noopener">Gin 运行多个服务&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.kancloud.cn/shuangdeyu/gin_book/949433" target="_blank" rel="noopener">XML、JSON、YAML 和 ProtoBuf 渲染（输出格式）&lt;/a>&lt;/li>
&lt;/ul>
&lt;h3 id="自定义路由日志的格式">自定义路由日志的格式&lt;/h3>
&lt;p>default&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">[&lt;/span>GIN-debug&lt;span style="color:#f92672">]&lt;/span> POST /foo --&amp;gt; main.main.func1 &lt;span style="color:#f92672">(&lt;/span>&lt;span style="color:#ae81ff">3&lt;/span> handlers&lt;span style="color:#f92672">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">[&lt;/span>GIN-debug&lt;span style="color:#f92672">]&lt;/span> GET /bar --&amp;gt; main.main.func2 &lt;span style="color:#f92672">(&lt;/span>&lt;span style="color:#ae81ff">3&lt;/span> handlers&lt;span style="color:#f92672">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">[&lt;/span>GIN-debug&lt;span style="color:#f92672">]&lt;/span> GET /status --&amp;gt; main.main.func3 &lt;span style="color:#f92672">(&lt;/span>&lt;span style="color:#ae81ff">3&lt;/span> handlers&lt;span style="color:#f92672">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> (
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;log&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;net/http&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;github.com/gin-gonic/gin&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">func&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">r&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">gin&lt;/span>.&lt;span style="color:#a6e22e">Default&lt;/span>()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">gin&lt;/span>.&lt;span style="color:#a6e22e">DebugPrintRouteFunc&lt;/span> = &lt;span style="color:#66d9ef">func&lt;/span>(&lt;span style="color:#a6e22e">httpMethod&lt;/span>, &lt;span style="color:#a6e22e">absolutePath&lt;/span>, &lt;span style="color:#a6e22e">handlerName&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span>, &lt;span style="color:#a6e22e">nuHandlers&lt;/span> &lt;span style="color:#66d9ef">int&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">log&lt;/span>.&lt;span style="color:#a6e22e">Printf&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;endpoint %v %v %v %v\n&amp;#34;&lt;/span>, &lt;span style="color:#a6e22e">httpMethod&lt;/span>, &lt;span style="color:#a6e22e">absolutePath&lt;/span>, &lt;span style="color:#a6e22e">handlerName&lt;/span>, &lt;span style="color:#a6e22e">nuHandlers&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">r&lt;/span>.&lt;span style="color:#a6e22e">POST&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;/foo&amp;#34;&lt;/span>, &lt;span style="color:#66d9ef">func&lt;/span>(&lt;span style="color:#a6e22e">c&lt;/span> &lt;span style="color:#f92672">*&lt;/span>&lt;span style="color:#a6e22e">gin&lt;/span>.&lt;span style="color:#a6e22e">Context&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">c&lt;/span>.&lt;span style="color:#a6e22e">JSON&lt;/span>(&lt;span style="color:#a6e22e">http&lt;/span>.&lt;span style="color:#a6e22e">StatusOK&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;foo&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> })
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">r&lt;/span>.&lt;span style="color:#a6e22e">GET&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;/bar&amp;#34;&lt;/span>, &lt;span style="color:#66d9ef">func&lt;/span>(&lt;span style="color:#a6e22e">c&lt;/span> &lt;span style="color:#f92672">*&lt;/span>&lt;span style="color:#a6e22e">gin&lt;/span>.&lt;span style="color:#a6e22e">Context&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">c&lt;/span>.&lt;span style="color:#a6e22e">JSON&lt;/span>(&lt;span style="color:#a6e22e">http&lt;/span>.&lt;span style="color:#a6e22e">StatusOK&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;bar&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> })
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">r&lt;/span>.&lt;span style="color:#a6e22e">GET&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;/status&amp;#34;&lt;/span>, &lt;span style="color:#66d9ef">func&lt;/span>(&lt;span style="color:#a6e22e">c&lt;/span> &lt;span style="color:#f92672">*&lt;/span>&lt;span style="color:#a6e22e">gin&lt;/span>.&lt;span style="color:#a6e22e">Context&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">c&lt;/span>.&lt;span style="color:#a6e22e">JSON&lt;/span>(&lt;span style="color:#a6e22e">http&lt;/span>.&lt;span style="color:#a6e22e">StatusOK&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;ok&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> })
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// Listen and Server in http://0.0.0.0:8080&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">r&lt;/span>.&lt;span style="color:#a6e22e">Run&lt;/span>()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="gin-运行多个服务">Gin 运行多个服务&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">package&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">import&lt;/span> (
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;log&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;net/http&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;time&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;github.com/gin-gonic/gin&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;golang.org/x/sync/errgroup&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">var&lt;/span> (
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">g&lt;/span> &lt;span style="color:#a6e22e">errgroup&lt;/span>.&lt;span style="color:#a6e22e">Group&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">func&lt;/span> &lt;span style="color:#a6e22e">router01&lt;/span>() &lt;span style="color:#a6e22e">http&lt;/span>.&lt;span style="color:#a6e22e">Handler&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">e&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">gin&lt;/span>.&lt;span style="color:#a6e22e">New&lt;/span>()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">e&lt;/span>.&lt;span style="color:#a6e22e">Use&lt;/span>(&lt;span style="color:#a6e22e">gin&lt;/span>.&lt;span style="color:#a6e22e">Recovery&lt;/span>())
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">e&lt;/span>.&lt;span style="color:#a6e22e">GET&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;/&amp;#34;&lt;/span>, &lt;span style="color:#66d9ef">func&lt;/span>(&lt;span style="color:#a6e22e">c&lt;/span> &lt;span style="color:#f92672">*&lt;/span>&lt;span style="color:#a6e22e">gin&lt;/span>.&lt;span style="color:#a6e22e">Context&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">c&lt;/span>.&lt;span style="color:#a6e22e">JSON&lt;/span>(
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">http&lt;/span>.&lt;span style="color:#a6e22e">StatusOK&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">gin&lt;/span>.&lt;span style="color:#a6e22e">H&lt;/span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;code&amp;#34;&lt;/span>: &lt;span style="color:#a6e22e">http&lt;/span>.&lt;span style="color:#a6e22e">StatusOK&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;error&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;Welcome server 01&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> },
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> )
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> })
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#a6e22e">e&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">func&lt;/span> &lt;span style="color:#a6e22e">router02&lt;/span>() &lt;span style="color:#a6e22e">http&lt;/span>.&lt;span style="color:#a6e22e">Handler&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">e&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">gin&lt;/span>.&lt;span style="color:#a6e22e">New&lt;/span>()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">e&lt;/span>.&lt;span style="color:#a6e22e">Use&lt;/span>(&lt;span style="color:#a6e22e">gin&lt;/span>.&lt;span style="color:#a6e22e">Recovery&lt;/span>())
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">e&lt;/span>.&lt;span style="color:#a6e22e">GET&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;/&amp;#34;&lt;/span>, &lt;span style="color:#66d9ef">func&lt;/span>(&lt;span style="color:#a6e22e">c&lt;/span> &lt;span style="color:#f92672">*&lt;/span>&lt;span style="color:#a6e22e">gin&lt;/span>.&lt;span style="color:#a6e22e">Context&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">c&lt;/span>.&lt;span style="color:#a6e22e">JSON&lt;/span>(
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">http&lt;/span>.&lt;span style="color:#a6e22e">StatusOK&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">gin&lt;/span>.&lt;span style="color:#a6e22e">H&lt;/span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;code&amp;#34;&lt;/span>: &lt;span style="color:#a6e22e">http&lt;/span>.&lt;span style="color:#a6e22e">StatusOK&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;error&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;Welcome server 02&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> },
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> )
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> })
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#a6e22e">e&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">func&lt;/span> &lt;span style="color:#a6e22e">main&lt;/span>() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">server01&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#f92672">&amp;amp;&lt;/span>&lt;span style="color:#a6e22e">http&lt;/span>.&lt;span style="color:#a6e22e">Server&lt;/span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Addr&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;:8080&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Handler&lt;/span>: &lt;span style="color:#a6e22e">router01&lt;/span>(),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">ReadTimeout&lt;/span>: &lt;span style="color:#ae81ff">5&lt;/span> &lt;span style="color:#f92672">*&lt;/span> &lt;span style="color:#a6e22e">time&lt;/span>.&lt;span style="color:#a6e22e">Second&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">WriteTimeout&lt;/span>: &lt;span style="color:#ae81ff">10&lt;/span> &lt;span style="color:#f92672">*&lt;/span> &lt;span style="color:#a6e22e">time&lt;/span>.&lt;span style="color:#a6e22e">Second&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">server02&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#f92672">&amp;amp;&lt;/span>&lt;span style="color:#a6e22e">http&lt;/span>.&lt;span style="color:#a6e22e">Server&lt;/span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Addr&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;:8081&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">Handler&lt;/span>: &lt;span style="color:#a6e22e">router02&lt;/span>(),
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">ReadTimeout&lt;/span>: &lt;span style="color:#ae81ff">5&lt;/span> &lt;span style="color:#f92672">*&lt;/span> &lt;span style="color:#a6e22e">time&lt;/span>.&lt;span style="color:#a6e22e">Second&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">WriteTimeout&lt;/span>: &lt;span style="color:#ae81ff">10&lt;/span> &lt;span style="color:#f92672">*&lt;/span> &lt;span style="color:#a6e22e">time&lt;/span>.&lt;span style="color:#a6e22e">Second&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">g&lt;/span>.&lt;span style="color:#a6e22e">Go&lt;/span>(&lt;span style="color:#66d9ef">func&lt;/span>() &lt;span style="color:#66d9ef">error&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#a6e22e">server01&lt;/span>.&lt;span style="color:#a6e22e">ListenAndServe&lt;/span>()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> })
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">g&lt;/span>.&lt;span style="color:#a6e22e">Go&lt;/span>(&lt;span style="color:#66d9ef">func&lt;/span>() &lt;span style="color:#66d9ef">error&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#a6e22e">server02&lt;/span>.&lt;span style="color:#a6e22e">ListenAndServe&lt;/span>()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> })
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">:=&lt;/span> &lt;span style="color:#a6e22e">g&lt;/span>.&lt;span style="color:#a6e22e">Wait&lt;/span>(); &lt;span style="color:#a6e22e">err&lt;/span> &lt;span style="color:#f92672">!=&lt;/span> &lt;span style="color:#66d9ef">nil&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">log&lt;/span>.&lt;span style="color:#a6e22e">Fatal&lt;/span>(&lt;span style="color:#a6e22e">err&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="xmljsonyaml-和-protobuf-渲染输出格式">XML、JSON、YAML 和 ProtoBuf 渲染（输出格式）&lt;/h3>
&lt;h4 id="securejson">SecureJSON&lt;/h4>
&lt;blockquote>
&lt;p>使用 SecureJSON 可以防止 json 劫持，如果返回的数据是数组，则会默认在返回值前加上&amp;quot;while(1)&amp;quot;&lt;/p></description></item><item><title>docker-compose yaml 問題</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210719-docker-compose-yaml-problem/</link><pubDate>Mon, 19 Jul 2021 15:40:36 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210719-docker-compose-yaml-problem/</guid><description>&lt;h4 id="問題">問題&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># ./docker-compose up -d&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Creating network &lt;span style="color:#e6db74">&amp;#34;gogs_default&amp;#34;&lt;/span> with the default driver
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Creating gogs_mysql_1 ... &lt;span style="color:#66d9ef">done&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Creating gogs_gogs_1 ... error
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>ERROR: &lt;span style="color:#66d9ef">for&lt;/span> gogs_gogs_1 Cannot create container &lt;span style="color:#66d9ef">for&lt;/span> service gogs: invalid port specification: &lt;span style="color:#e6db74">&amp;#34;133342&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>ERROR: &lt;span style="color:#66d9ef">for&lt;/span> gogs Cannot create container &lt;span style="color:#66d9ef">for&lt;/span> service gogs: invalid port specification: &lt;span style="color:#e6db74">&amp;#34;133342&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>ERROR: Encountered errors &lt;span style="color:#66d9ef">while&lt;/span> bringing up the project.
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">services&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">gogs&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">ports&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">2222&lt;/span>:&lt;span style="color:#ae81ff">22&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>YAML 支援所謂的「六十進位浮點數」，這對時間計算很有用。&lt;/p>
&lt;p>因此，&lt;code>2222:22&lt;/code> 會被解讀為 &lt;code>2222 * 60 + 22&lt;/code>，也就是 133342。&lt;/p>
&lt;p>如果連接埠包含大於 60 的數字，例如 3306:3306 或 8080:80，就不會有問題，所以這個問題不一定會出現，因而比較不容易察覺。&lt;/p>
&lt;h4 id="解法">解法&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">services&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">gogs&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">ports&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#e6db74">&amp;#34;2222:22&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>在瀏覽器輸入網址並送出後，到底發生了什麼事？</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210718-what-happens-when-you-type-an-url-in-the-browser-and-press-enter/</link><pubDate>Sun, 18 Jul 2021 23:45:45 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210718-what-happens-when-you-type-an-url-in-the-browser-and-press-enter/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://www.cythilya.tw/2018/11/26/what-happens-when-you-type-an-url-in-the-browser-and-press-enter/" target="_blank" rel="noopener">在瀏覽器輸入網址並送出後，到底發生了什麼事？&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>我就感觉到快 —— zsh 和 oh my zsh 冷启动速度优化</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210715-make-oh-my-zsh-fly/</link><pubDate>Thu, 15 Jul 2021 18:19:06 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210715-make-oh-my-zsh-fly/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://blog.skk.moe/post/make-oh-my-zsh-fly/" target="_blank" rel="noopener">我就感觉到快 —— zsh 和 oh my zsh 冷启动速度优化&lt;/a>&lt;/li>
&lt;/ul>
&lt;h4 id="profiling">Profiling&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># .zshrc&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>zmodload zsh/zprof
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>$ /bin/zsh
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ zprof
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>num calls time self name
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>-----------------------------------------------------------------------------------
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 1&lt;span style="color:#f92672">)&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span> 395.66 395.66 33.10% 395.59 395.59 33.09% _zsh_nvm_auto_use
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 2&lt;span style="color:#f92672">)&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span> 216.22 216.22 18.09% 216.13 216.13 18.08% nvm_die_on_prefix
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 3&lt;span style="color:#f92672">)&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span> 648.00 648.00 54.20% 168.85 168.85 14.12% nvm_auto
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 4&lt;span style="color:#f92672">)&lt;/span> &lt;span style="color:#ae81ff">2&lt;/span> 479.15 239.57 40.08% 160.50 80.25 13.43% nvm
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 5&lt;span style="color:#f92672">)&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span> 102.30 102.30 8.56% 84.99 84.99 7.11% nvm_ensure_version_installed
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 6&lt;span style="color:#f92672">)&lt;/span> &lt;span style="color:#ae81ff">2&lt;/span> 51.21 25.60 4.28% 29.55 14.78 2.47% compinit
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 7&lt;span style="color:#f92672">)&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span> 680.18 680.18 56.89% 22.17 22.17 1.85% _zsh_nvm_load
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 8&lt;span style="color:#f92672">)&lt;/span> &lt;span style="color:#ae81ff">2&lt;/span> 21.66 10.83 1.81% 21.66 10.83 1.81% compaudit
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 9&lt;span style="color:#f92672">)&lt;/span> &lt;span style="color:#ae81ff">1&lt;/span> 17.31 17.31 1.45% 17.31 17.31 1.45% nvm_is_version_installed
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>10&lt;span style="color:#f92672">)&lt;/span> &lt;span style="color:#ae81ff">193&lt;/span> 17.43 0.09 1.46% 14.50 0.08 1.21% _zsh_autosuggest_bind_widget
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">[&lt;/span>Redacted&lt;span style="color:#f92672">]&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;code>zprof&lt;/code> 模块只能获取每个 zsh 函数的用时，因此适合找出拖累 zsh 冷启动的 oh my zsh 的插件。如果要获取完整的 &lt;code>.zshrc&lt;/code> 性能分析，应该使用 &lt;code>xtrace&lt;/code>。在 &lt;code>.zshrc&lt;/code> 开头添加如下命令&lt;/p></description></item><item><title>[網友好文]Cisco UCS CIMC系列文章</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210715-cisco-ucs-cimc/</link><pubDate>Thu, 15 Jul 2021 17:16:52 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210715-cisco-ucs-cimc/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://ansible.cloudns.pro/post/cisco-ucs-cimc/" target="_blank" rel="noopener">[網友好文]Cisco UCS CIMC 系列文章&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.weithenn.org/2021/06/ansible-for-cisco-ucs-cimc.html" target="_blank" rel="noopener">Ansible - 設定 Cisco UCS CIMC 時區&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.weithenn.org/2021/06/ansible-for-cisco-ucs-cimc-dns-ipv6.html" target="_blank" rel="noopener">Ansible - 設定 Cisco UCS CIMC DNS 和停用 IPv6&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.weithenn.org/2021/06/ansible-cisco-ucs-cimc-fan-policy.html" target="_blank" rel="noopener">Ansible - 設定 Cisco UCS CIMC Fan Policy&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.weithenn.org/2021/06/ansible-cisco-ucs-cimc-mail-alert.html" target="_blank" rel="noopener">Ansible - 設定 Cisco UCS CIMC Mail Alert&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.weithenn.org/2021/06/ansible-cisco-ucs-cimc-40gb-vnic.html" target="_blank" rel="noopener">Ansible - 設定 Cisco UCS CIMC 40Gb vNIC 參數&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://www.weithenn.org/2021/07/ansible-cisco-ucs-cimc-ntp.html" target="_blank" rel="noopener">Ansible - 設定 Cisco UCS CIMC NTP 時間校時&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>SQL 查詢不是從 SELECT 開始</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210714-sql-queries-don-t-start-with-select/</link><pubDate>Wed, 14 Jul 2021 18:11:46 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210714-sql-queries-don-t-start-with-select/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://jvns.ca/blog/2019/10/03/sql-queries-don-t-start-with-select/" target="_blank" rel="noopener">SQL 查詢不是從 SELECT 開始&lt;/a>&lt;/li>
&lt;/ul>
&lt;h4 id="sql-查詢實際執行順序">SQL 查詢實際執行順序&lt;/h4>
&lt;ul>
&lt;li>&lt;code>FROM/JOIN&lt;/code> 以及所有 &lt;code>ON&lt;/code> 條件&lt;/li>
&lt;li>&lt;code>WHERE&lt;/code>&lt;/li>
&lt;li>&lt;code>GROUP BY&lt;/code>&lt;/li>
&lt;li>&lt;code>HAVING&lt;/code>&lt;/li>
&lt;li>&lt;code>SELECT&lt;/code>（包含視窗函式）&lt;/li>
&lt;li>&lt;code>ORDER BY&lt;/code>&lt;/li>
&lt;li>&lt;code>LIMIT&lt;/code>&lt;/li>
&lt;/ul></description></item><item><title>多數程式設計師不知道的 6 個 YAML 特性</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210707-6-yaml-features-most-programmers-dont-know/</link><pubDate>Wed, 07 Jul 2021 15:08:31 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210707-6-yaml-features-most-programmers-dont-know/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://levelup.gitconnected.com/6-yaml-features-most-programmers-dont-know-164762343af3" target="_blank" rel="noopener">多數程式設計師不知道的 6 個 YAML 特性&lt;/a>&lt;/li>
&lt;/ul>
&lt;h4 id="還有更多類似的危險例子正如-tom-ritchford-所指出">還有更多類似的危險例子，正如 Tom Ritchford 所指出&lt;/h4>
&lt;ul>
&lt;li>&lt;code>013&lt;/code> 會被對應為 11，因為前導 0 會觸發八進位表示法&lt;/li>
&lt;li>&lt;code>4:30&lt;/code> 會被對應為 270。Max Werner Kaul-Gothe 與 Niklas Baumstark 告訴我，這會被自動轉換為分鐘（或秒）並被視為一段持續時間：&lt;code>4*60 + 30 = 270&lt;/code>。有趣的是，這個模式在 &lt;code>1:1:1:1:1:1:1:1:4:30&lt;/code> 仍然「可運作」。&lt;/li>
&lt;/ul>
&lt;h4 id="多行字串">多行字串&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">mail_signature&lt;/span>: |&lt;span style="color:#e6db74">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74"> Martin Thoma
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74"> Tel. +49 123 4567&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-json" data-lang="json">&lt;span style="display:flex;">&lt;span>{ &lt;span style="color:#f92672">&amp;#34;mail_signature&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;Martin Thoma\nTel. +49 123 4567&amp;#34;&lt;/span> }
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="錨點">錨點&lt;/h4>
&lt;blockquote>
&lt;p>&lt;code>&amp;amp;&lt;/code> 會定義一個名為 &lt;code>emailAddress&lt;/code> 的變數，值為 &lt;code>&amp;quot;info@example.de&amp;quot;&lt;/code>。&lt;code>*&lt;/code> 則表示接著的是變數名稱。&lt;/p>&lt;/blockquote>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">email&lt;/span>: &lt;span style="color:#75715e">&amp;amp;emailAddress&lt;/span> &lt;span style="color:#e6db74">&amp;#34;info@example.de&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">id&lt;/span>: &lt;span style="color:#75715e">*emailAddress&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-json" data-lang="json">&lt;span style="display:flex;">&lt;span>{ &lt;span style="color:#f92672">&amp;#34;email&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;info@example.de&amp;#34;&lt;/span>, &lt;span style="color:#f92672">&amp;#34;id&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;info@example.de&amp;#34;&lt;/span> }
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h5 id="也可以對映射這樣做">也可以對映射這樣做&lt;/h5>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">foo&lt;/span>: &lt;span style="color:#75715e">&amp;amp;default_settings&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">db&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">host&lt;/span>: &lt;span style="color:#ae81ff">localhost&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">name&lt;/span>: &lt;span style="color:#ae81ff">main_db&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">port&lt;/span>: &lt;span style="color:#ae81ff">1337&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">email&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">admin&lt;/span>: &lt;span style="color:#ae81ff">admin@example.com&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">prod&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;lt;&amp;lt;&lt;/span>: &lt;span style="color:#75715e">*default_settings&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">app&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">port&lt;/span>: &lt;span style="color:#ae81ff">80&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">dev&lt;/span>: &lt;span style="color:#75715e">*default_settings&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-json" data-lang="json">&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;#34;foo&amp;#34;&lt;/span>: {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;#34;db&amp;#34;&lt;/span>: { &lt;span style="color:#f92672">&amp;#34;host&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;localhost&amp;#34;&lt;/span>, &lt;span style="color:#f92672">&amp;#34;name&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;main_db&amp;#34;&lt;/span>, &lt;span style="color:#f92672">&amp;#34;port&amp;#34;&lt;/span>: &lt;span style="color:#ae81ff">1337&lt;/span> },
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;#34;email&amp;#34;&lt;/span>: { &lt;span style="color:#f92672">&amp;#34;admin&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;admin@example.com&amp;#34;&lt;/span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> },
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;#34;prod&amp;#34;&lt;/span>: {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;#34;app&amp;#34;&lt;/span>: { &lt;span style="color:#f92672">&amp;#34;port&amp;#34;&lt;/span>: &lt;span style="color:#ae81ff">80&lt;/span> },
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;#34;db&amp;#34;&lt;/span>: { &lt;span style="color:#f92672">&amp;#34;host&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;localhost&amp;#34;&lt;/span>, &lt;span style="color:#f92672">&amp;#34;name&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;main_db&amp;#34;&lt;/span>, &lt;span style="color:#f92672">&amp;#34;port&amp;#34;&lt;/span>: &lt;span style="color:#ae81ff">1337&lt;/span> },
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;#34;email&amp;#34;&lt;/span>: { &lt;span style="color:#f92672">&amp;#34;admin&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;admin@example.com&amp;#34;&lt;/span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> },
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;#34;dev&amp;#34;&lt;/span>: {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;#34;db&amp;#34;&lt;/span>: { &lt;span style="color:#f92672">&amp;#34;host&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;localhost&amp;#34;&lt;/span>, &lt;span style="color:#f92672">&amp;#34;name&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;main_db&amp;#34;&lt;/span>, &lt;span style="color:#f92672">&amp;#34;port&amp;#34;&lt;/span>: &lt;span style="color:#ae81ff">1337&lt;/span> },
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;#34;email&amp;#34;&lt;/span>: { &lt;span style="color:#f92672">&amp;#34;admin&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;admin@example.com&amp;#34;&lt;/span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="型別轉換">型別轉換&lt;/h4>
&lt;blockquote>
&lt;p>雙驚嘆號 &lt;code>!!&lt;/code> 在 YAML 中有特殊意義。它稱為「secondary tag handle」，是 &lt;code>!tag:yaml.org,2002&lt;/code> 的簡寫。&lt;/p></description></item><item><title>用 Markdown 繪製圖表</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210629-draw-diagrams-with-markdown/</link><pubDate>Tue, 29 Jun 2021 15:55:35 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210629-draw-diagrams-with-markdown/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://support.typora.io/Draw-Diagrams-With-Markdown/#sequence-diagrams" target="_blank" rel="noopener">用 Markdown 繪製圖表&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>ansible.builtin.slurp - 讀取檔案內容</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210531-slurp-read-file-content/</link><pubDate>Mon, 31 May 2021 17:15:04 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210531-slurp-read-file-content/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://ansible.cloudns.pro/post/slurp-read-file-content/" target="_blank" rel="noopener">ansible.builtin.slurp - 讀取檔案內容&lt;/a>&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>---
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>- &lt;span style="color:#f92672">name&lt;/span>: &lt;span style="color:#ae81ff">Use HTTP POST to upload file&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">hosts&lt;/span>: &lt;span style="color:#ae81ff">all&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">tasks&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#f92672">name&lt;/span>: &lt;span style="color:#ae81ff">Read binary file content&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">slurp&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">path&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;/bin/ls&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">register&lt;/span>: &lt;span style="color:#ae81ff">bin_file&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#f92672">name&lt;/span>: &lt;span style="color:#ae81ff">Send HTTP POST Request&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">uri&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">url&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;https://your_server/upload.php&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">headers&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">Accept&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;application/json&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">Content-Type&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;application/octet-stream&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">method&lt;/span>: &lt;span style="color:#ae81ff">POST&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">validate_certs&lt;/span>: &lt;span style="color:#66d9ef">false&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">body&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;{{ bin_file.content }}&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">status_code&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">200&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#ae81ff">201&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">register&lt;/span>: &lt;span style="color:#ae81ff">upload_result&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - &lt;span style="color:#f92672">name&lt;/span>: &lt;span style="color:#ae81ff">Display upload_result&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">debug&lt;/span>:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">var&lt;/span>: &lt;span style="color:#ae81ff">upload_result&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>使用 slurp，就可以避掉 lookup(&amp;lsquo;file&amp;rsquo;) 的限制。&lt;/p>
&lt;ul>
&lt;li>可以讀取受控端主機上的檔案，也可以利用 delegate_to: localhost 來讀取主控端主機上的檔案。&lt;/li>
&lt;li>可以讀取二進位檔案來做進一步處理，例如做 base64 編碼&lt;/li>
&lt;/ul></description></item><item><title>Nginx - request_time和upstream_response_time详解</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210514-105819628/</link><pubDate>Fri, 14 May 2021 16:04:04 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210514-105819628/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://blog.csdn.net/zzhongcy/article/details/105819628" target="_blank" rel="noopener">Nginx - request_time 和 upstream_response_time 详解&lt;/a>&lt;/li>
&lt;/ul>
&lt;h3 id="time-definition">time definition&lt;/h3>
&lt;p>&lt;strong>request_time&lt;/strong>&lt;/p>
&lt;p>从接受用户请求的第一个字节到发送完响应数据的时间，即&lt;code>$request_time&lt;/code> 包括接收客户端请求数据的时间、后端程序响应的时间、发送响应数据给客户端的时间(不包含写日志的时间)。&lt;/p>
&lt;p>&lt;strong>upstream_response_time&lt;/strong>&lt;/p>
&lt;p>从 Nginx 向后端建立连接开始到接受完数据然后关闭连接为止的时间&lt;/p>
&lt;p>&lt;strong>upstream_connect_time&lt;/strong>&lt;/p>
&lt;p>跟后端 server 建立连接的时间，如果是到后端使用了加密的协议，该时间将包括握手的时间。&lt;/p>
&lt;p>&lt;strong>upstream_header_time&lt;/strong>&lt;/p>
&lt;p>接收后端 server 响应头的时间&lt;/p>
&lt;p>如果把整个过程补充起来的话 应该是：&lt;/p>
&lt;p>&lt;code>［1用户请求］［2建立 Nginx 连接］［3发送响应］［4接收响应］［5关闭 Nginx 连接］&lt;/code>&lt;/p>
&lt;ul>
&lt;li>那么 &lt;code>upstream_response_time&lt;/code> 就是 &lt;code>2+3+4+5&lt;/code>&lt;/li>
&lt;li>但是 一般这里面可以认为 &lt;code>［5关闭 Nginx 连接］&lt;/code> 的耗时接近 0&lt;/li>
&lt;li>所以 &lt;code>upstream_response_time&lt;/code> 实际上就是 &lt;code>2+3+4&lt;/code>&lt;/li>
&lt;li>而 &lt;code>request_time&lt;/code> 是 &lt;code>1+2+3+4&lt;/code>&lt;/li>
&lt;li>二者之间相差的就是 &lt;code>［1用户请求］&lt;/code>的时间。&lt;/li>
&lt;/ul>
&lt;h4 id="upstream_response_time-比-request_time-大">upstream_response_time 比 request_time 大&lt;/h4>
&lt;blockquote>
&lt;p>&lt;a href="https://forum.nginx.org/read.php?21,284448,284450#msg-284450" target="_blank" rel="noopener">https://forum.nginx.org/read.php?21,284448,284450#msg-284450&lt;/a>&lt;/p>&lt;/blockquote>
&lt;p>&lt;code>$upstream_response_time&lt;/code> 由 &lt;code>clock_gettime(CLOCK_MONOTONIC_COARSE)&lt;/code>计算，默认情况下，它可以过去 4 毫秒，相反，&lt;code>$request_time&lt;/code> 由 &lt;code>gettimeofday()&lt;/code>计算。 所以最终 upstream_response_time 可能比 response_time 更大。&lt;/p></description></item><item><title>在 bash 腳本中使用 here-doc 將資料寫入檔案</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210507-using-heredoc-rediection-in-bash-shell-script-to-write-to-file/</link><pubDate>Fri, 07 May 2021 11:37:35 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210507-using-heredoc-rediection-in-bash-shell-script-to-write-to-file/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://www.cyberciti.biz/faq/using-heredoc-rediection-in-bash-shell-script-to-write-to-file/" target="_blank" rel="noopener">在 bash 腳本中使用 here-doc 將資料寫入檔案&lt;/a>&lt;/li>
&lt;/ul>
&lt;h4 id="使用-eof--讓-here-doc-在-shell-腳本中可自然縮排">使用 &lt;code>EOF&amp;lt;&amp;lt;-&lt;/code> 讓 here-doc 在 shell 腳本中可自然縮排&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>command &lt;span style="color:#e6db74">&amp;lt;&amp;lt;-EOF
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74"> msg1
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74"> msg2
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74"> $var on line
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">EOF&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="使用-eof-停用路徑參數變數展開命令替換與算術展開">使用 &lt;code>'EOF'&lt;/code> 停用路徑/參數/變數展開、命令替換與算術展開&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#!/bin/bash
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>OUT&lt;span style="color:#f92672">=&lt;/span>/tmp/output.txt
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>echo &lt;span style="color:#e6db74">&amp;#34;Starting my script...&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>echo &lt;span style="color:#e6db74">&amp;#34;Doing something...&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># No parameter and variable expansion, command substitution, arithmetic expansion, or pathname expansion is performed on word.&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># If any part of word is quoted, the delimiter is the result of quote removal on word, and the lines in the here-document&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># are not expanded. So EOF is quoted as follows&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>cat &lt;span style="color:#e6db74">&amp;lt;&amp;lt;&amp;#39;EOF&amp;#39; &amp;gt;$OUT
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74"> Status of backup as on $(date)
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74"> Backing up files $HOME and /etc/
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">EOF&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>echo &lt;span style="color:#e6db74">&amp;#34;Starting backup using rsync...&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>升級到 Zabbix 5 後資料庫升級失敗</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210503-upgrade-database-failed-after-ugrade-to-zabbix-5/</link><pubDate>Mon, 03 May 2021 16:33:23 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210503-upgrade-database-failed-after-ugrade-to-zabbix-5/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://www.zabbix.com/forum/zabbix-troubleshooting-and-problems/403139-upgrade-database-failed-after-ugrade-to-zabbix-5" target="_blank" rel="noopener">升級到 Zabbix 5 後資料庫升級失敗&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://bestmonitoringtools.com/upgrade-zabbix-to-the-latest-version/" target="_blank" rel="noopener">Zabbix 4.0/4.2/4.4 升級到 5.0/5.2 的逐步指南&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>高效能 Go 工作坊</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210428-gophercon-2019/</link><pubDate>Wed, 28 Apr 2021 16:37:05 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210428-gophercon-2019/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://dave.cheney.net/high-performance-go-workshop/gophercon-2019.html" target="_blank" rel="noopener">高效能 Go 工作坊&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>通过 Nginx 绕过 X-Frame-Options 限制</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210426-nginx-x-frame-options/</link><pubDate>Mon, 26 Apr 2021 17:39:33 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210426-nginx-x-frame-options/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://blog.whezh.com/nginx-x-frame-options/" target="_blank" rel="noopener">通过 Nginx 绕过 X-Frame-Options 限制&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>&lt;code>X-Frame-Options&lt;/code> HTTP 响应头是用来给浏览器指示允许一个页面是否可以在 &lt;code>&amp;lt;frame&amp;gt;&lt;/code>,&lt;code> &amp;lt;iframe&amp;gt;&lt;/code>, &lt;code>&amp;lt;embed&amp;gt;&lt;/code> 或者 &lt;code>&amp;lt;object&amp;gt;&lt;/code> 中展现的标记。站点可以通过确保网站没有被嵌入到别人的站点里面，从而避免 Clickjacking 攻击。通过 Nginx 的作为正向代理，我们可以绕过 &lt;code>X-Frame-Options&lt;/code> 限制成功的将第三方网页嵌入到自己的页面中。&lt;/p>
&lt;p>X-Frame-Options 响应头有三个可能的值：&lt;/p>
&lt;ul>
&lt;li>deny: 表示该页面不允许在 frame 中展示，即便是在相同域名的页面中嵌套也不允许。&lt;/li>
&lt;li>sameorigin: 表示该页面可以在相同域名页面的 frame 中展示。&lt;/li>
&lt;li>allow-from uri: 表示该页面可以在指定来源的 frame 中展示。&lt;/li>
&lt;/ul>
&lt;p>在 Chrome 尝试加载 frame 的内容时，如果 X-Frame-Options 响应头设置为禁止访问，那么 Chrome 会在控制台中显示如下错误。
&lt;code>Refuse to display 'http://192.168.20.101:8080' in a frame because it set 'X-Frame-Options' to 'deny'.&lt;/code>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-nginx" data-lang="nginx">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">server&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">listen&lt;/span> &lt;span style="color:#ae81ff">8080&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">location&lt;/span> &lt;span style="color:#e6db74">/&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">proxy_hide_header&lt;/span> &lt;span style="color:#e6db74">X-Frame-Options&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">proxy_pass&lt;/span> &lt;span style="color:#e6db74">http://&lt;/span>{&lt;span style="color:#f92672">target}&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>这也当请求 &lt;code>http://{proxy_server}:8080&lt;/code> 时，nginx 会做代理转发到 &lt;code>http://{target}&lt;/code>，同时在返回结果的时候会隐藏掉 &lt;code>X-Frame-Options&lt;/code> 相应头，这样我们自己的网页就能正常通过 iFrame 载入目标网页了。&lt;/p></description></item><item><title>Setting up JWT Authentication</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210423-configuring-jwt-authentication/</link><pubDate>Fri, 23 Apr 2021 11:13:34 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210423-configuring-jwt-authentication/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://docs.nginx.com/nginx/admin-guide/security-controls/configuring-jwt-authentication/" target="_blank" rel="noopener">Setting up JWT Authentication&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://segmentfault.com/a/1190000015677681" target="_blank" rel="noopener">Nginx 实现 JWT 验证-基于 OpenResty 实现&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>SSH 失敗錯誤：fatal: daemon() failed: No such device</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210304-ssh-failing-with-error-fatal-daemon-failed-no-such-device/</link><pubDate>Thu, 04 Mar 2021 18:48:39 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210304-ssh-failing-with-error-fatal-daemon-failed-no-such-device/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://admin-ahead.com/forum/general-linux/ssh-failing-with-error-fatal-daemon%28%29-failed-no-such-device/" target="_blank" rel="noopener">SSH 失敗錯誤：fatal: daemon() failed: No such device&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>/var/log/secure&lt;/p>
&lt;p>&lt;code>Oct 10 10:58:05 vps sshd[23799]: fatal: daemon() failed: No such device&lt;/code>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># rm -vf /dev/null&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>removed &lt;span style="color:#e6db74">`&lt;/span>/dev/null&lt;span style="color:#e6db74">`&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>-bash-3.2# mknod /dev/null c &lt;span style="color:#ae81ff">1&lt;/span> &lt;span style="color:#ae81ff">3&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Started SSH and the SSH started responding:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># service sshd restart&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Stopping sshd: &lt;span style="color:#f92672">[&lt;/span> OK &lt;span style="color:#f92672">]&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Starting sshd: &lt;span style="color:#f92672">[&lt;/span> OK &lt;span style="color:#f92672">]&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>-bash-3.2# service sshd status
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>openssh-daemon &lt;span style="color:#f92672">(&lt;/span>pid 30608&lt;span style="color:#f92672">)&lt;/span> is running…
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>GitLab 啟用 Project integration - Mattermost slash commands</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210128-gitlab-mattermost-slash-commands/</link><pubDate>Thu, 28 Jan 2021 11:50:41 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210128-gitlab-mattermost-slash-commands/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://blog.chengweichen.com/2021/01/gitlab-mattermost-slash-commands.html" target="_blank" rel="noopener">GitLab 啟用 Project integration - Mattermost slash commands&lt;/a>&lt;/li>
&lt;/ul></description></item><item><title>Nginx SSL/TLS configuration with TLSv1.2 and TLSv1.3 - ECDHE and strong ciphers suite (Openssl 1.1.1)</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210122-7d432c3c3d134cc3cb7e98b30a76c287/</link><pubDate>Fri, 22 Jan 2021 13:49:17 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210122-7d432c3c3d134cc3cb7e98b30a76c287/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://gist.github.com/VirtuBox/7d432c3c3d134cc3cb7e98b30a76c287" target="_blank" rel="noopener">Nginx SSL/TLS configuration with TLSv1.2 and TLSv1.3 - ECDHE and strong ciphers suite (Openssl 1.1.1)&lt;/a>&lt;/li>
&lt;/ul>
&lt;h5 id="sslconf">ssl.conf&lt;/h5>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-nginx" data-lang="nginx">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">##
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># SSL Settings (TLSv1.2 and TLSv1.3)
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">##
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#66d9ef">ssl_protocols&lt;/span> &lt;span style="color:#e6db74">TLSv1.2&lt;/span> &lt;span style="color:#e6db74">TLSv1.3&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">ssl_ciphers&lt;/span> &lt;span style="color:#e6db74">&amp;#39;TLS13+AESGCM+AES128:EECDH+AES128&amp;#39;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">ssl_prefer_server_ciphers&lt;/span> &lt;span style="color:#66d9ef">on&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">ssl_session_cache&lt;/span> &lt;span style="color:#e6db74">shared:SSL:50m&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">ssl_session_timeout&lt;/span> &lt;span style="color:#e6db74">1d&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">ssl_session_tickets&lt;/span> &lt;span style="color:#66d9ef">off&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">ssl_ecdh_curve&lt;/span> &lt;span style="color:#e6db74">X25519:sect571r1:secp521r1:secp384r1&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h5 id="universal-sslconf">universal-ssl.conf&lt;/h5>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-nginx" data-lang="nginx">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">##
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># SSL Settings (TLSv1.0 + TLSv1.1 + TLSv1.2 + TLSv1.3)
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">##
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#66d9ef">ssl_protocols&lt;/span> &lt;span style="color:#e6db74">TLSv1&lt;/span> &lt;span style="color:#e6db74">TLSv1.1&lt;/span> &lt;span style="color:#e6db74">TLSv1.2&lt;/span> &lt;span style="color:#e6db74">TLSv1.3&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">ssl_ciphers&lt;/span> &lt;span style="color:#e6db74">&amp;#39;TLS13+AESG+AES128:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES25GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:DHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-R-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-S:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS&amp;#39;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">ssl_prefer_server_ciphers&lt;/span> &lt;span style="color:#66d9ef">on&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">ssl_session_cache&lt;/span> &lt;span style="color:#e6db74">shared:SSL:50m&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">ssl_session_timeout&lt;/span> &lt;span style="color:#e6db74">1d&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">ssl_session_tickets&lt;/span> &lt;span style="color:#66d9ef">off&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">ssl_ecdh_curve&lt;/span> &lt;span style="color:#e6db74">X25519:sect571r1:secp521r1:secp384r1&lt;/span>;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>ZSH 自动读取 macOS 系统代理配置并设置环境变量</title><link>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210111-macos-auto-read-proxy-settings-zsh/</link><pubDate>Mon, 11 Jan 2021 14:50:11 +0800</pubDate><guid>https://9855cc0f.linzeyan.pages.dev/zh-tw/posts/2021/20210111-macos-auto-read-proxy-settings-zsh/</guid><description>&lt;ul>
&lt;li>&lt;a href="https://blog.skk.moe/post/macos-auto-read-proxy-settings-zsh/" target="_blank" rel="noopener">ZSH 自动读取 macOS 系统代理配置并设置环境变量&lt;/a>&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-zsh" data-lang="zsh">&lt;span style="display:flex;">&lt;span>$ system_profiler SPNetworkDataType &lt;span style="color:#75715e"># 获取完整网络配置信息&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ networksetup -listallnetworkservices &lt;span style="color:#75715e"># 列举所有网络设备&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ networksetup -getwebproxy Wi-Fi &lt;span style="color:#75715e"># 获取特定网络设备的系统代理配置&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ scutil --proxy &lt;span style="color:#75715e"># 获取当前已启用的代理配置，是对 system_profiler 的封装&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item></channel></rss>