<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>v2ee</title><link>https://www.v2ee.top/</link><description>V2EE CENTER</description><language>zh-CN</language><atom:link href="https://www.v2ee.top/feed/index.xml" rel="self" type="application/rss+xml"/><item><title>编译安装ffmpeg，并编译cuda相关</title><link>https://www.v2ee.top/archives/290.html</link><guid isPermaLink="true">https://www.v2ee.top/archives/290.html</guid><pubDate>Wed, 13 Aug 2025 12:03:00 +0800</pubDate><description>&lt;h3 id="步骤-1确保-nvidia-驱动和-cuda-toolkit-已安装"&gt;&lt;strong&gt;步骤 1：确保 NVIDIA 驱动和 CUDA Toolkit 已安装&lt;/strong&gt;&lt;/h3&gt;
&lt;h4 id="1-检查-nvidia-驱动"&gt;&lt;strong&gt;(1) 检查 NVIDIA 驱动&lt;/strong&gt;&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;nvidia-smi &lt;span style="color:#75715e"&gt;# 确保驱动已安装，且版本 ≥ 450.80.02&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果未安装，请：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Ubuntu/Debian&lt;/strong&gt;：
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo apt install nvidia-driver-535 &lt;span style="color:#75715e"&gt;# 推荐最新版&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CentOS/RHEL&lt;/strong&gt;：
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo dnf install nvidia-driver
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="2-安装-cuda-toolkit"&gt;&lt;strong&gt;(2) 安装 CUDA Toolkit&lt;/strong&gt;&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 官方 CUDA 安装指南（选择适合的版本）：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# https://developer.nvidia.com/cuda-downloads&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Ubuntu/Debian 示例：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/cuda-keyring_1.1-1_all.deb
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo dpkg -i cuda-keyring_1.1-1_all.deb
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo apt update
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo apt install -y cuda-toolkit-12-3 &lt;span style="color:#75715e"&gt;# 安装 CUDA 12.3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;安装后，确保 &lt;code&gt;nvcc&lt;/code&gt; 可用：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;nvcc --version &lt;span style="color:#75715e"&gt;# 应输出 CUDA 版本&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="3-设置环境变量"&gt;&lt;strong&gt;(3) 设置环境变量&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;在 &lt;code&gt;~/.bashrc&lt;/code&gt; 或 &lt;code&gt;~/.zshrc&lt;/code&gt; 添加：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;export PATH&lt;span style="color:#f92672"&gt;=&lt;/span&gt;/usr/local/cuda/bin:$PATH
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;export LD_LIBRARY_PATH&lt;span style="color:#f92672"&gt;=&lt;/span&gt;/usr/local/cuda/lib64:$LD_LIBRARY_PATH
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;然后刷新：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;source ~/.bashrc
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id="步骤-2重新编译-ffmpeg确保启用-cuda-和-npp"&gt;&lt;strong&gt;步骤 2：重新编译 FFmpeg（确保启用 CUDA 和 NPP）&lt;/strong&gt;&lt;/h3&gt;
&lt;h4 id="1-安装依赖"&gt;&lt;strong&gt;(1) 安装依赖&lt;/strong&gt;&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Ubuntu/Debian&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo apt update
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo apt install -y build-essential yasm cmake libx264-dev libx265-dev libnpp-dev
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="2-下载-ffmpeg-源码选择兼容驱动的版本"&gt;&lt;strong&gt;(2) 下载 FFmpeg 源码，选择兼容驱动的版本&lt;/strong&gt;&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git clone https://git.ffmpeg.org/ffmpeg.git -b release/6.1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cd ffmpeg
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="3-配置时确保启用-cuda-和-npp"&gt;&lt;strong&gt;(3) 配置时确保启用 CUDA 和 NPP&lt;/strong&gt;&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;./configure &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --enable-nonfree &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --enable-cuda-nvcc &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --enable-libnpp &lt;span style="color:#ae81ff"&gt;\ &lt;/span&gt; &lt;span style="color:#75715e"&gt;# 关键！启用 NVIDIA Performance Primitives&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --enable-filter&lt;span style="color:#f92672"&gt;=&lt;/span&gt;hwupload_cuda &lt;span style="color:#ae81ff"&gt;\ &lt;/span&gt; &lt;span style="color:#75715e"&gt;# 显式启用 CUDA 过滤器&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --enable-filter&lt;span style="color:#f92672"&gt;=&lt;/span&gt;scale_npp &lt;span style="color:#ae81ff"&gt;\ &lt;/span&gt; &lt;span style="color:#75715e"&gt;# 显式启用 NPP 缩放&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --extra-cflags&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;-I/usr/local/cuda/include&amp;#34;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --extra-ldflags&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;-L/usr/local/cuda/lib64&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;make -j&lt;span style="color:#66d9ef"&gt;$(&lt;/span&gt;nproc&lt;span style="color:#66d9ef"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo make install
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="4-验证编译结果"&gt;&lt;strong&gt;(4) 验证编译结果&lt;/strong&gt;&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ffmpeg -hide_banner -filters | grep -E &lt;span style="color:#e6db74"&gt;&amp;#34;cuda|npp&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;输出应包含：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;hwupload_cuda
scale_npp
overlay_cuda
&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h3 id="步骤-3测试-ffmpeg-硬件加速"&gt;&lt;strong&gt;步骤 3：测试 FFmpeg 硬件加速&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;运行测试命令：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ffmpeg -hwaccel cuda -i input.mp4 -vf &lt;span style="color:#e6db74"&gt;&amp;#34;hwupload_cuda,scale_npp=w=1280:h=720&amp;#34;&lt;/span&gt; -c:v h264_nvenc output.mp4
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果成功，说明 CUDA 加速已正常工作。&lt;/p&gt;
&lt;hr&gt;
&lt;hr&gt;
&lt;h2 id="1-问题"&gt;&lt;strong&gt;1. 问题&lt;/strong&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;ffnvcodec&lt;/code&gt; 缺失&lt;/strong&gt;：这是 NVIDIA 的 FFmpeg 编解码器头文件，用于硬件加速。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;libnpp&lt;/code&gt; 未正确链接&lt;/strong&gt;：NVIDIA Performance Primitives (NPP) 库可能未安装或版本不匹配。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="2-解决方案"&gt;&lt;strong&gt;2. 解决方案&lt;/strong&gt;&lt;/h2&gt;
&lt;h3 id="步骤-1安装"&gt;&lt;strong&gt;步骤 1：安装 &lt;code&gt;ffnvcodec&lt;/code&gt;&lt;/strong&gt;&lt;/h3&gt;
&lt;h4 id="1-下载"&gt;&lt;strong&gt;(1) 下载 &lt;code&gt;nv-codec-headers&lt;/code&gt;（即 &lt;code&gt;ffnvcodec&lt;/code&gt;）&lt;/strong&gt;&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git clone https://git.videolan.org/git/ffmpeg/nv-codec-headers.git
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cd nv-codec-headers
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;make
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo make install &lt;span style="color:#75715e"&gt;# 默认安装到 /usr/local/include/ffnvcodec&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="2-确保头文件能被找到"&gt;&lt;strong&gt;(2) 确保头文件能被找到&lt;/strong&gt;&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;export PKG_CONFIG_PATH&lt;span style="color:#f92672"&gt;=&lt;/span&gt;/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;（如果 &lt;code&gt;/usr/local/include/ffnvcodec&lt;/code&gt; 不存在，请检查安装路径）&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="步骤-2确保"&gt;&lt;strong&gt;步骤 2：确保 &lt;code&gt;libnpp&lt;/code&gt; 已安装&lt;/strong&gt;&lt;/h3&gt;
&lt;h4 id="1-安装"&gt;&lt;strong&gt;(1) 安装 &lt;code&gt;libnpp&lt;/code&gt;（NVIDIA Performance Primitives）&lt;/strong&gt;&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Ubuntu/Debian&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo apt install libnpp-dev &lt;span style="color:#75715e"&gt;# 关键！&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# CentOS/RHEL&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo yum install nvidia-npp-devel
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="2-检查"&gt;&lt;strong&gt;(2) 检查 &lt;code&gt;libnpp&lt;/code&gt; 版本&lt;/strong&gt;&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;dpkg -l | grep libnpp &lt;span style="color:#75715e"&gt;# Ubuntu/Debian&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rpm -qa | grep npp &lt;span style="color:#75715e"&gt;# CentOS/RHEL&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;确保版本与 CUDA Toolkit 匹配（如 CUDA 12.x 需要 &lt;code&gt;libnpp-12&lt;/code&gt;）。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="步骤-3重新编译-ffmpeg"&gt;&lt;strong&gt;步骤 3：重新编译 FFmpeg&lt;/strong&gt;&lt;/h3&gt;
&lt;h4 id="1-清理旧配置"&gt;&lt;strong&gt;(1) 清理旧配置&lt;/strong&gt;&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cd /path/to/ffmpeg
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;make distclean
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>WARP官方客户端手动注册Cloudflare Zero Trust教程</title><link>https://www.v2ee.top/archives/289.html</link><guid isPermaLink="true">https://www.v2ee.top/archives/289.html</guid><pubDate>Mon, 28 Jul 2025 16:45:00 +0800</pubDate><description>&lt;p&gt;本教程提供在没有图形界面的服务器上配置Cloudflare for Teams的一种方法。如无必要，使用一键脚本更快。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;安装WARP官方客户端，参考下方链接，如果直接复制命令记得提前安装：&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;sudo curl gpg lsb-release&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;https://pkg.cloudflareclient.com/&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;使用非root账号输入命令&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;warp-cli registration new &amp;lt;团队名称&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;同意许可协议&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在本机浏览器打开链接 &lt;code&gt;https://&amp;lt;团队名称&amp;gt;.cloudflareaccess.com/warp&lt;/code&gt; ，登录，对蓝色Open Cloudflare WARP按钮使用右键菜单点审查元素，看到形如下方代码&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;button id=&amp;quot;redirect-button&amp;quot; onclick=&amp;quot;location.href = 'com.cloudflare.warp://&amp;lt;团队名称&amp;gt;.cloudflareaccess.com/auth?token=一堆乱码';&amp;quot; class=&amp;quot;Button Button-is-juicy Approve Success&amp;quot;&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;复制单引号包裹的链接&lt;code&gt;com.cloudflare.warp://&amp;lt;团队名称&amp;gt;.cloudflareaccess.com/auth?token=一堆乱码&lt;/code&gt;，注意不要复制单引号&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;回到命令行，输入以下命令，同意许可协议，完成注册&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;warp-cli registration token &amp;lt;刚刚复制的链接&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;使用warp-cli connect连接WARP，注意提前在Zero Trust里设置默认代理模式，否则可能会造成小鸡入口失效（控制面板 -&amp;gt; Zero Trust -&amp;gt; Settings -&amp;gt; WARP Client -&amp;gt; Device settings -&amp;gt; Default -&amp;gt; Edit -&amp;gt; Service mode -&amp;gt; 选择Proxy mode）&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>配置apt强制使用ipv4</title><link>https://www.v2ee.top/archives/283.html</link><guid isPermaLink="true">https://www.v2ee.top/archives/283.html</guid><pubDate>Wed, 11 Jan 2023 10:08:00 +0800</pubDate><description>&lt;p&gt;Force IPv4 using APT&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;#/bin/bash
echo &amp;#39;Acquire::ForceIPv4 &amp;#34;true&amp;#34;;&amp;#39; | sudo tee /etc/apt/apt.conf.d/99force-ipv4
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>nginx动态模块编译</title><link>https://www.v2ee.top/archives/281.html</link><guid isPermaLink="true">https://www.v2ee.top/archives/281.html</guid><pubDate>Wed, 25 May 2022 10:22:00 +0800</pubDate><description>&lt;h3 id="下载对应版本的nginx"&gt;下载对应版本的&lt;code&gt;nginx&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://nginx.org/"&gt;nginx&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="下载相应模块"&gt;下载相应模块&lt;/h3&gt;
&lt;p&gt;编译前需要&lt;code&gt;pcre&lt;/code&gt;和&lt;code&gt;zlib&lt;/code&gt;都需要下载&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;tar xvf nginx.tar.gz
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cd nginx
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;make clean
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;./configure --with-pcre&lt;span style="color:#f92672"&gt;=&lt;/span&gt;../pcre-8.45 --with-zlib&lt;span style="color:#f92672"&gt;=&lt;/span&gt;../zlib-1.2.11 --with-openssl&lt;span style="color:#f92672"&gt;=&lt;/span&gt;/usr/bin --add-dynamic-module&lt;span style="color:#f92672"&gt;=&lt;/span&gt;../&amp;lt;模块目录&amp;gt; --with-compat
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;make
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cd objs
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Linux通过inode值删除特殊字符文件</title><link>https://www.v2ee.top/archives/280.html</link><guid isPermaLink="true">https://www.v2ee.top/archives/280.html</guid><pubDate>Tue, 25 Jan 2022 11:34:13 +0800</pubDate><description>&lt;p&gt;使用&lt;code&gt;ls -i&lt;/code&gt;查询文件inode值
使用&lt;code&gt;find&lt;/code&gt;命令删除&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;find ./ -inum inode -delete
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;或者&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;find ./ -inum inode | xargs rm -rf
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>[转载]网站添加一段代码防止被举报，在QQ/微信打开时提示在浏览器打开网站</title><link>https://www.v2ee.top/archives/279.html</link><guid isPermaLink="true">https://www.v2ee.top/archives/279.html</guid><pubDate>Fri, 26 Nov 2021 11:38:00 +0800</pubDate><description>&lt;p&gt;&lt;a href="https://w.a-ro.cn/1710.html"&gt;转载自 十二.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;添加一段代码，即可让网站在微信和QQ中打开网站时提示让用户在浏览器打开，极大的减少网站被举报和屏蔽。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;script&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 跳转提示
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;is_weixn_qq&lt;/span&gt;()) {;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; window.&lt;span style="color:#a6e22e"&gt;location&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;href&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;‘&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;https&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#75715e"&gt;//c.pc.qq.com/middle.html?pfurl=’+window.location.href;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;is_weixn_qq&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 判断当前是否微信/QQ浏览器
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ua&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;navigator&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;userAgent&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;isWeixin&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;!!&lt;/span&gt;&lt;span style="color:#e6db74"&gt;/MicroMessenger/i&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;test&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;ua&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;isQQ&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;!!&lt;/span&gt;&lt;span style="color:#e6db74"&gt;/QQ\//i&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;test&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;ua&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;isWeixin&lt;/span&gt;&lt;span style="color:#f92672"&gt;||&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;isQQ&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;/script&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>css中设置table中的td内容自动换行</title><link>https://www.v2ee.top/archives/css%E4%B8%AD%E8%AE%BE%E7%BD%AEtable%E4%B8%AD%E7%9A%84td%E5%86%85%E5%AE%B9%E8%87%AA%E5%8A%A8%E6%8D%A2%E8%A1%8C.html</link><guid isPermaLink="true">https://www.v2ee.top/archives/css%E4%B8%AD%E8%AE%BE%E7%BD%AEtable%E4%B8%AD%E7%9A%84td%E5%86%85%E5%AE%B9%E8%87%AA%E5%8A%A8%E6%8D%A2%E8%A1%8C.html</guid><pubDate>Wed, 01 Apr 2020 16:02:29 +0800</pubDate><description>&lt;p&gt;在项目中，有用到表格。因为有的内容比较长，所以需要列宽大一些，有的内容比较短，列宽就小一些。遇到了一个问题，在学校联系方式表里面，联系人电话/电子邮件这两列，无论我加多大的宽度，内容总是会把表格列撑的很宽，百度了一下，发现原因是这样的：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;一般字母的话会被浏览器默认是一个字符串或者说一个单词，所以不会自动换行&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;所以需要设置一下，让表格内容自动换行。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1.在中设置样式style为&lt;code&gt;word-wrap:break-word;word-break:break-all;&lt;/code&gt;（一般情况只需要设置&lt;code&gt;word-break:break-all&lt;/code&gt;即可，但是有时候需要加&lt;code&gt;word-wrap:break-word&lt;/code&gt; ）&lt;/li&gt;
&lt;li&gt;2.把表格的sytle的&lt;code&gt;table-layout：fixed&lt;/code&gt;，就是表格固定宽度，就是表格既要自适应他外面的容器，也不要撑出去，然后设置td的&lt;code&gt;word-wrap：break-word&lt;/code&gt;；换行，问题就解决了&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>在Linux系统下用dd命令制作ISO镜像U盘启动盘</title><link>https://www.v2ee.top/archives/%E5%9C%A8Linux%E7%B3%BB%E7%BB%9F%E4%B8%8B%E7%94%A8dd%E5%91%BD%E4%BB%A4%E5%88%B6%E4%BD%9CISO%E9%95%9C%E5%83%8FU%E7%9B%98%E5%90%AF%E5%8A%A8%E7%9B%98.html</link><guid isPermaLink="true">https://www.v2ee.top/archives/%E5%9C%A8Linux%E7%B3%BB%E7%BB%9F%E4%B8%8B%E7%94%A8dd%E5%91%BD%E4%BB%A4%E5%88%B6%E4%BD%9CISO%E9%95%9C%E5%83%8FU%E7%9B%98%E5%90%AF%E5%8A%A8%E7%9B%98.html</guid><pubDate>Wed, 04 Dec 2019 12:05:11 +0800</pubDate><description>&lt;ol&gt;
&lt;li&gt;插入U盘，&lt;code&gt;df -h&lt;/code&gt;查看U盘文件系统挂载情况，然后使用&lt;code&gt;umount /dev/sdb*&lt;/code&gt;卸载U盘文件系统&lt;/li&gt;
&lt;li&gt;执行命令：&lt;code&gt;sudo mkfs.vfat -I /dev/sdb&lt;/code&gt;格式化U盘为FAT格式&lt;/li&gt;
&lt;li&gt;&lt;code&gt;dd if=*/*.iso of=/dev/sdb bs=4M&lt;/code&gt; (数据块大小，每个数据块只能存一个文件的数据)&lt;/li&gt;
&lt;li&gt;执行&lt;code&gt;sync&lt;/code&gt;，同步缓存中的数据至U盘&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>MySQL8+添加用户及更新权限</title><link>https://www.v2ee.top/archives/273.html</link><guid isPermaLink="true">https://www.v2ee.top/archives/273.html</guid><pubDate>Fri, 26 Jul 2019 11:59:03 +0800</pubDate><description>&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;CREATE&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;USER&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;admin&lt;/span&gt;&lt;span style="color:#f92672"&gt;@&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;%&amp;#39;&lt;/span&gt; IDENTIFIED &lt;span style="color:#66d9ef"&gt;BY&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;123456&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;GRANT&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;ALL&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;PRIVILEGES&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;ON&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;.&lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;TO&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;admin&lt;/span&gt;&lt;span style="color:#f92672"&gt;@&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;%&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;FLUSH &lt;span style="color:#66d9ef"&gt;PRIVILEGES&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Linux添加虚拟网卡</title><link>https://www.v2ee.top/archives/Linux%E6%B7%BB%E5%8A%A0%E8%99%9A%E6%8B%9F%E7%BD%91%E5%8D%A1.html</link><guid isPermaLink="true">https://www.v2ee.top/archives/Linux%E6%B7%BB%E5%8A%A0%E8%99%9A%E6%8B%9F%E7%BD%91%E5%8D%A1.html</guid><pubDate>Thu, 20 Jun 2019 14:39:33 +0800</pubDate><description>&lt;h3 id="通过修改配置修改虚拟网卡"&gt;通过修改配置修改虚拟网卡&lt;/h3&gt;
&lt;p&gt;打开配置文件&lt;code&gt;/etc/network/interfaces&lt;/code&gt;， 添加一下配置。&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;auto eth0:0
iface eth0:0 inet static
address 192.168.1.63
netmask 255.255.255.0
network 192.168.1.1
broadcast 192.168.1.255
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;使用&lt;code&gt;:&lt;/code&gt;符号开启来标识虚拟网卡，虚拟网卡必须依托实体网卡的标识。
最后执行服务重启。&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;sudo /etc/init.d/networking restart
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>SpringCloud各个组件说明</title><link>https://www.v2ee.top/archives/SpringCloud%E5%90%84%E4%B8%AA%E7%BB%84%E4%BB%B6%E8%AF%B4%E6%98%8E.html</link><guid isPermaLink="true">https://www.v2ee.top/archives/SpringCloud%E5%90%84%E4%B8%AA%E7%BB%84%E4%BB%B6%E8%AF%B4%E6%98%8E.html</guid><pubDate>Thu, 13 Jun 2019 17:44:43 +0800</pubDate><description>&lt;p&gt;对于SpringCloud来说，首先我们需要认识一些基本的组件，这会让我们之后的讨论和交流更有效率。&lt;/p&gt;
&lt;h3 id="组件名字和发音"&gt;组件名字和发音&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Eureka [jʊ&amp;#39;ri:kə]
Ribbon [ˈrɪbən]
Feign [fen]
Hystrix [hɪst&amp;#39;rɪks]
Zuul [zulu]
Sleuth [sluθ]
Turbine [ˈtɜ:rbaɪn]
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="重要组件说明"&gt;重要组件说明&lt;/h3&gt;
&lt;p&gt;这里的说明借用网上一个很6的分类方式来说明。
润物无声类和独挑大梁类。&lt;/p&gt;
&lt;p&gt;独挑大梁，独自启动不需要依赖其它组件。
&lt;code&gt;Eureka&lt;/code&gt;，服务注册中心，特性有失效剔除、服务保护。（类似生活中的大堂，登记了整个项目的所有服务）
&lt;code&gt;Dashboard&lt;/code&gt;，&lt;code&gt;Hystrix&lt;/code&gt;仪表盘，监控集群模式和单点模式，其中集群模式需要收集器&lt;code&gt;Turbine&lt;/code&gt;配合。（类似生活中的保安监控室）
&lt;code&gt;Zuul&lt;/code&gt;，API服务网关，功能有路由分发和过滤。（类似交警叔叔，指挥道路交通）
&lt;code&gt;Config&lt;/code&gt;，分布式配置中心，支持本地仓库、&lt;code&gt;SVN&lt;/code&gt;、&lt;code&gt;Git&lt;/code&gt;、&lt;code&gt;Jar&lt;/code&gt;包内配置等模式。（类似规章制度，每个人都从这里获取规定配置）&lt;/p&gt;
&lt;p&gt;润物无声，融合在每个微服务中、依赖其它组件并为其提供服务。
&lt;code&gt;Ribbon&lt;/code&gt;，客户端负载均衡，特性有区域亲和、重试机制。（类似&lt;code&gt;nginx&lt;/code&gt;）
&lt;code&gt;Hystrix&lt;/code&gt;，客户端容错保护，特性有服务降级、服务熔断、请求缓存、请求合并、依赖隔离。（怕访问过于频繁服务挂了，进行限流，太频繁的请求就直接拒绝）
&lt;code&gt;Feign&lt;/code&gt;，声明式服务调用，本质上就是&lt;code&gt;Ribbon&lt;/code&gt;+&lt;code&gt;Hystrix&lt;/code&gt;。（用注解的方式进行服务调用，代码更好看了）
&lt;code&gt;Stream&lt;/code&gt;，消息驱动，有&lt;code&gt;Sink&lt;/code&gt;、&lt;code&gt;Source&lt;/code&gt;、&lt;code&gt;Processor&lt;/code&gt;三种通道，特性有订阅发布、消费组、消息分区。
&lt;code&gt;Bus&lt;/code&gt;，消息总线，配合&lt;code&gt;Config&lt;/code&gt;仓库修改的一种&lt;code&gt;Stream&lt;/code&gt;实现。（用于广播消息，一说大家都知道了啦）
&lt;code&gt;Sleuth&lt;/code&gt;，分布式服务追踪，需要搞清楚&lt;code&gt;TraceID&lt;/code&gt;和&lt;code&gt;SpanID&lt;/code&gt;以及抽样，如何与&lt;code&gt;ELK&lt;/code&gt;整合。（服务多了，调用的线路就会很复杂，需要跟踪来知道你到底是怎么走的）&lt;/p&gt;</description></item><item><title>Kill user tty/pts sessions in Linux</title><link>https://www.v2ee.top/archives/Kill-user-tty-pts-sessions-in-Linux.html</link><guid isPermaLink="true">https://www.v2ee.top/archives/Kill-user-tty-pts-sessions-in-Linux.html</guid><pubDate>Mon, 27 May 2019 16:21:00 +0800</pubDate><description>&lt;h3 id="kill-user-ttypts-sessions-in-linux"&gt;Kill user tty/pts sessions in Linux&lt;/h3&gt;
&lt;h4 id="commands"&gt;Commands&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;w&lt;/code&gt;: show who is logged on and what they are doing&lt;/li&gt;
&lt;li&gt;&lt;code&gt;who&lt;/code&gt;: show who is logged on&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tty&lt;/code&gt;: show current users pseudo terminal&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ps -ft pts/1&lt;/code&gt;: get process id for the pseudo terminal&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pkill&lt;/code&gt;: signal process based on name and other attributes&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;Check active users logged into the server with: &lt;code&gt;w&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt; 16:53:37 up 23:46, 2 users, load average: 0.00, 0.00, 0.00
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
ubuntu pts/1 127.0.0.1 16:45 0.00s 0.04s 0.00s w
ubuntu pts/2 127.0.0.1:S.0 16:35 16.00s 0.02s 0.02s /bin/bash
&lt;/code&gt;&lt;/pre&gt;&lt;ol start="2"&gt;
&lt;li&gt;Get the PID (Process ID) of a connected terminal (tty) with: &lt;code&gt;ps -ft pts/1&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;UID PID PPID C STIME TTY TIME CMD
ubuntu 28580 28102 0 16:45 pts/1 00:00:00 -bash
ubuntu 29081 28580 0 16:55 pts/1 00:00:00 ps -ft pts/1
&lt;/code&gt;&lt;/pre&gt;&lt;ol start="3"&gt;
&lt;li&gt;
&lt;p&gt;Kill the process: &lt;code&gt;kill 28580&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Alternatively use &lt;code&gt;pkill -t pts/1&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>WSL中PATH删除Windows环境变量</title><link>https://www.v2ee.top/archives/WSL%E4%B8%ADPATH%E5%88%A0%E9%99%A4Windows%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F.html</link><guid isPermaLink="true">https://www.v2ee.top/archives/WSL%E4%B8%ADPATH%E5%88%A0%E9%99%A4Windows%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F.html</guid><pubDate>Sat, 25 May 2019 00:25:00 +0800</pubDate><description>&lt;p&gt;WSL_DISTRIBUTION_FLAGS&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-C++" data-lang="C++"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;typedef&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;enum&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;_WSL_DISTRIBUTION_FLAGS&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; WSL_DISTRIBUTION_FLAGS_NONE &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; WSL_DISTRIBUTION_FLAGS_ENABLE_INTEROP &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; WSL_DISTRIBUTION_FLAGS_APPEND_NT_PATH &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; WSL_DISTRIBUTION_FLAGS_ENABLE_DRIVE_MOUNTING &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;} WSL_DISTRIBUTION_FLAGS;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;This flag is stored in HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Lxss\{GUID}\Flags. It&amp;#39;s default value is 7.
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Beyond Compare 4 Crack</title><link>https://www.v2ee.top/archives/Beyond-Compare-4-Crack.html</link><guid isPermaLink="true">https://www.v2ee.top/archives/Beyond-Compare-4-Crack.html</guid><pubDate>Wed, 23 Jan 2019 16:01:00 +0800</pubDate><description>&lt;h1 id="crack-beyond-compare-linux"&gt;Crack-Beyond-Compare-linux&lt;/h1&gt;
&lt;p&gt;&lt;a href="https://github.com/jyma1991/Crack-Beyond-Compare-linux.git"&gt;crack beyond compare 4 on linux&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="1官网下载最新版-beyond-compare-4-并安装"&gt;1.官网下载最新版 Beyond Compare 4 并安装&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.scootersoftware.com/download.php"&gt;Beyond Compare 4&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;安装命令：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-vim" data-lang="vim"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;sudo&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;apt&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;install&lt;/span&gt; -&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;bcompare&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;-4&lt;/span&gt;.&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;.&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;.&lt;span style="color:#ae81ff"&gt;22587&lt;/span&gt;_amd&lt;span style="color:#ae81ff"&gt;64&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;deb&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果报错 “依赖关系问题 - 仍未被配置” 使用如下命令&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-vim" data-lang="vim"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;sudo&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;apt&lt;/span&gt;-&lt;span style="color:#a6e22e"&gt;get&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;install&lt;/span&gt; -&lt;span style="color:#a6e22e"&gt;f&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;等分析完之后重新执行安装命令&lt;/p&gt;
&lt;h2 id="2破解"&gt;2.破解&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-vim" data-lang="vim"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;cd&lt;/span&gt; &lt;span style="color:#e6db74"&gt;/usr/&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;lib&lt;/span&gt;&lt;span style="color:#e6db74"&gt;/beyondcompare/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;sudo&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;sed&lt;/span&gt; -&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;s/keexjEP3t4Mue23hrnuPtY4TdcsqNiJL-5174TsUdLmJSIXKfG2NGPwBL6vnRPddT7tH29qpkneX63DO9ECSPE9rzY1zhThHERg8lHM9IBFT+rVuiY823aQJuqzxCKIE1bcDqM4wgW01FH6oCBP1G4ub01xmb4BGSUG6ZrjxWHJyNLyIlGvOhoY2HAYzEtzYGwxFZn2JZ66o4RONkXjX0DF9EzsdUef3UAS+JQ+fCYReLawdjEe6tXCv88GKaaPKWxCeaUL9PejICQgRQOLGOZtZQkLgAelrOtehxz5ANOOqCaJgy2mJLQVLM5SJ9Dli909c5ybvEhVmIC0dc9dWH+/N9KmiLVlKMU7RJqnE+WXEEPI1SgglmfmLc1yVH7dqBb9ehOoKG9UE+HAE1YvH1XX2XVGeEqYUY-Tsk7YBTz0WpSpoYyPgx6Iki5KLtQ5G-aKP9eysnkuOAkrvHU8bLbGtZteGwJarev03PhfCioJL4OSqsmQGEvDbHFEbNl1qJtdwEriR+VNZts9vNNLk7UGfeNwIiqpxjk4Mn09nmSd8FhM4ifvcaIbNCRoMPGl6KU12iseSe+w+1kFsLhX+OhQM8WXcWV10cGqBzQE9OqOLUcg9n0krrR3KrohstS9smTwEx9olyLYppvC0p5i7dAx2deWvM1ZxKNs0BvcXGukR+/g&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;BCompare&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="3此时bcompare文件已被破解打开软件会提示trial-mode-error表示成功输入下面team-zwt生成的密钥即可注册成功"&gt;3.此时BCompare文件已被破解，打开软件会提示“Trial Mode Error！”表示成功，输入下面TEAM ZWT生成的密钥即可注册成功&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-nohighlight" data-lang="nohighlight"&gt;--- BEGIN LICENSE KEY ---
GXN1eh9FbDiX1ACdd7XKMV7hL7x0ClBJLUJ-zFfKofjaj2yxE53xauIfkqZ8FoLpcZ0Ux6McTyNmODDSvSIHLYhg1QkTxjCeSCk6ARz0ABJcnUmd3dZYJNWFyJun14rmGByRnVPL49QH+Rs0kjRGKCB-cb8IT4Gf0Ue9WMQ1A6t31MO9jmjoYUeoUmbeAQSofvuK8GN1rLRv7WXfUJ0uyvYlGLqzq1ZoJAJDyo0Kdr4ThF-IXcv2cxVyWVW1SaMq8GFosDEGThnY7C-SgNXW30jqAOgiRjKKRX9RuNeDMFqgP2cuf0NMvyMrMScnM1ZyiAaJJtzbxqN5hZOMClUTE+++
--- END LICENSE KEY -----
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="4成功后在目录configbcompare下会生成文件bc4keytxt-如下"&gt;4.成功后在目录~/.config/bcompare/下会生成文件BC4Key.txt 如下&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-nohighlight" data-lang="nohighlight"&gt;Beyond Compare 4
Licensed to: pwelyn
Quantity: 9999 users
Serial number: 9571-9981
License type: Pro Edition for Windows/Linux/OS X
--- BEGIN LICENSE KEY ---
GXN1eh9FbDiX1ACdd7XKMV7hL7x0ClBJLUJ-zFfKofjaj2yxE53xauIfk
qZ8FoLpcZ0Ux6McTyNmODDSvSIHLYhg1QkTxjCeSCk6ARz0ABJcnUmd3d
ZYJNWFyJun14rmGByRnVPL49QH+Rs0kjRGKCB-cb8IT4Gf0Ue9WMQ1A6t
31MO9jmjoYUeoUmbeAQSofvuK8GN1rLRv7WXfUJ0uyvYlGLqzq1ZoJAJD
yo0Kdr4ThF-IXcv2cxVyWVW1SaMq8GFosDEGThnY7C-SgNXW30jqAOgiR
jKKRX9RuNeDMFqgP2cuf0NMvyMrMScnM1ZyiAaJJtzbxqN5hZOMClUTE+
--- END LICENSE KEY -----
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="5为所有用户注册bcompare-命令"&gt;5.为所有用户注册bcompare 命令&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-vim" data-lang="vim"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;sudo&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;cp&lt;/span&gt; ~&lt;span style="color:#e6db74"&gt;/.config/&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;bcompare&lt;/span&gt;&lt;span style="color:#e6db74"&gt;/BC4Key.txt /&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;etc&lt;/span&gt;/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="6后期更新后只需要执行第五步"&gt;6.后期更新后只需要执行第五步&lt;/h2&gt;</description></item><item><title>parted命令，调整分区大小，修复分区表信息</title><link>https://www.v2ee.top/archives/parted%E5%91%BD%E4%BB%A4-%E8%B0%83%E6%95%B4%E5%88%86%E5%8C%BA%E5%A4%A7%E5%B0%8F-%E4%BF%AE%E5%A4%8D%E5%88%86%E5%8C%BA%E8%A1%A8%E4%BF%A1%E6%81%AF.html</link><guid isPermaLink="true">https://www.v2ee.top/archives/parted%E5%91%BD%E4%BB%A4-%E8%B0%83%E6%95%B4%E5%88%86%E5%8C%BA%E5%A4%A7%E5%B0%8F-%E4%BF%AE%E5%A4%8D%E5%88%86%E5%8C%BA%E8%A1%A8%E4%BF%A1%E6%81%AF.html</guid><pubDate>Sun, 20 Jan 2019 23:35:45 +0800</pubDate><description>&lt;p&gt;&lt;code&gt;parted&lt;/code&gt;命令是由GNU组织开发的一款功能强大的磁盘分区和分区大小调整工具，与&lt;code&gt;fdisk&lt;/code&gt;不同，它支持调整分区的大小。作为一种设计用于Linux的工具，它没有构建成处理与&lt;code&gt;fdisk&lt;/code&gt;关联的多种分区类型，但是，它可以处理最常见的分区格式，包括：&lt;code&gt;ext2、ext3、fat16、fat32、NTFS、ReiserFS、JFS、XFS、UFS、HFS&lt;/code&gt;以及Linux交换分区。&lt;/p&gt;
&lt;h3 id="语法"&gt;语法&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;parted(选项)(参数)
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="选项"&gt;选项&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;-h：显示帮助信息；
-i：交互式模式；
-s：脚本模式，不提示用户；
-v：显示版本号。
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="操作命令"&gt;操作命令&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;MINOR #对文件系统进行一个简单的检查
cp [FROM-DEVICE] FROM-MINOR TO-MINOR #将文件系统复制到另一个分区
help [COMMAND] #打印通用求助信息，或关于 COMMAND 的信息
mklabel 标签类型 #创建新的磁盘标签 (分区表)
mkfs MINOR 文件系统类型 #在 MINOR 创建类型为“文件系统类型”的文件系统
mkpart 分区类型 [文件系统类型] 起始点 终止点 #创建一个分区
mkpartfs 分区类型 文件系统类型 起始点 终止点 #创建一个带有文件系统的分区
move MINOR 起始点 终止点 #移动编号为 MINOR 的分区
name MINOR 名称 #将编号为 MINOR 的分区命名为“名称”
print [MINOR] #打印分区表，或者分区
quit #退出程序
rescue 起始点 终止点 #挽救临近“起始点”、“终止点”的遗失的分区
resize MINOR 起始点 终止点 #改变位于编号为 MINOR 的分区中文件系统的大小
rm MINOR #删除编号为 MINOR 的分区
select 设备 #选择要编辑的设备
set MINOR 标志 状态 #改变编号为 MINOR 的分区的标志
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>清除内存cache缓存</title><link>https://www.v2ee.top/archives/265.html</link><guid isPermaLink="true">https://www.v2ee.top/archives/265.html</guid><pubDate>Mon, 07 Jan 2019 14:07:00 +0800</pubDate><description>&lt;p&gt;Kernels 2.6.16 and newer provide a mechanism to have the kernel drop the page cache and/or inode and dentry caches on command, which can help free up a lot of memory. Now you can throw away that script that allocated a ton of memory just to get rid of the cache&amp;hellip;&lt;/p&gt;
&lt;p&gt;To use &lt;code&gt;/proc/sys/vm/drop_caches&lt;/code&gt;, just echo a number to it. defaults 0&lt;/p&gt;
&lt;p&gt;To free pagecache:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;echo 1 &amp;gt; /proc/sys/vm/drop_caches
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To free dentries and inodes:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;echo 2 &amp;gt; /proc/sys/vm/drop_caches
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To free pagecache, dentries and inodes:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;echo 3 &amp;gt; /proc/sys/vm/drop_caches
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is a non-destructive operation and will only free things that are completely unused. Dirty objects will continue to be in use until written out to disk and are not freeable. If you run &amp;ldquo;sync&amp;rdquo; first to flush them out to disk, these drop operations will tend to free more memory.&lt;/p&gt;</description></item><item><title>缓存穿透，缓存击穿，缓存雪崩</title><link>https://www.v2ee.top/archives/%E7%BC%93%E5%AD%98%E7%A9%BF%E9%80%8F-%E7%BC%93%E5%AD%98%E5%87%BB%E7%A9%BF-%E7%BC%93%E5%AD%98%E9%9B%AA%E5%B4%A9.html</link><guid isPermaLink="true">https://www.v2ee.top/archives/%E7%BC%93%E5%AD%98%E7%A9%BF%E9%80%8F-%E7%BC%93%E5%AD%98%E5%87%BB%E7%A9%BF-%E7%BC%93%E5%AD%98%E9%9B%AA%E5%B4%A9.html</guid><pubDate>Fri, 14 Sep 2018 15:11:00 +0800</pubDate><description>&lt;h3 id="前言"&gt;前言&lt;/h3&gt;
&lt;p&gt;设计一个缓存系统，不得不要考虑的问题就是：缓存穿透、缓存击穿与失效时的雪崩效应。&lt;/p&gt;
&lt;h3 id="缓存穿透"&gt;缓存穿透&lt;/h3&gt;
&lt;p&gt;缓存穿透是指查询一个一定不存在的数据，由于缓存是不命中时被动写的，并且出于容错考虑，如果从存储层查不到数据则不写入缓存，这将导致这个不存在的数据每次请求都要到存储层去查询，失去了缓存的意义。在流量大时，可能&lt;code&gt;DB&lt;/code&gt;就挂掉了，要是有人利用不存在的&lt;code&gt;key&lt;/code&gt;频繁攻击我们的应用，这就是漏洞。&lt;/p&gt;
&lt;h4 id="解决方案"&gt;解决方案&lt;/h4&gt;
&lt;p&gt;有很多种方法可以有效地解决缓存穿透问题，最常见的则是采用布隆过滤器，将所有可能存在的数据哈希到一个足够大的&lt;code&gt;bitmap&lt;/code&gt;中，一个一定不存在的数据会被 这个&lt;code&gt;bitmap&lt;/code&gt;拦截掉，从而避免了对底层存储系统的查询压力。另外也有一个更为简单粗暴的方法（我们采用的就是这种），如果一个查询返回的数据为空（不管是数 据不存在，还是系统故障），我们仍然把这个空结果进行缓存，但它的过期时间会很短，最长不超过五分钟。&lt;/p&gt;
&lt;h3 id="缓存雪崩"&gt;缓存雪崩&lt;/h3&gt;
&lt;p&gt;缓存雪崩是指在我们设置缓存时采用了相同的过期时间，导致缓存在某一时刻同时失效，请求全部转发到&lt;code&gt;DB&lt;/code&gt;，&lt;code&gt;DB&lt;/code&gt;瞬时压力过重雪崩。&lt;/p&gt;
&lt;h4 id="解决方案-1"&gt;解决方案&lt;/h4&gt;
&lt;p&gt;缓存失效时的雪崩效应对底层系统的冲击非常可怕。大多数系统设计者考虑用加锁或者队列的方式保证缓存的单线 程（进程）写，从而避免失效时大量的并发请求落到底层存储系统上。这里分享一个简单方案就时讲缓存失效时间分散开，比如我们可以在原有的失效时间基础上增加一个随机值，比如1-5分钟随机，这样每一个缓存的过期时间的重复率就会降低，就很难引发集体失效的事件。&lt;/p&gt;
&lt;h3 id="缓存击穿"&gt;缓存击穿&lt;/h3&gt;
&lt;p&gt;对于一些设置了过期时间的&lt;code&gt;key&lt;/code&gt;，如果这些&lt;code&gt;key&lt;/code&gt;可能会在某些时间点被超高并发地访问，是一种非常“热点”的数据。这个时候，需要考虑一个问题：缓存被“击穿”的问题，这个和缓存雪崩的区别在于这里针对某一&lt;code&gt;key&lt;/code&gt;缓存，前者则是很多&lt;code&gt;key&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;缓存在某个时间点过期的时候，恰好在这个时间点对这个&lt;code&gt;Key&lt;/code&gt;有大量的并发请求过来，这些请求发现缓存过期一般都会从后端DB加载数据并回设到缓存，这个时候大并发的请求可能会瞬间把后端&lt;code&gt;DB&lt;/code&gt;压垮。&lt;/p&gt;
&lt;h4 id="解决方案-2"&gt;解决方案&lt;/h4&gt;
&lt;h5 id="1使用互斥锁mutex-key"&gt;1.使用互斥锁(&lt;code&gt;mutex key&lt;/code&gt;)&lt;/h5&gt;
&lt;p&gt;业界比较常用的做法，是使用&lt;code&gt;mutex&lt;/code&gt;。简单地来说，就是在缓存失效的时候（判断拿出来的值为空），不是立即去&lt;code&gt;load db&lt;/code&gt;，而是先使用缓存工具的某些带成功操作返回值的操作（比如&lt;code&gt;Redis&lt;/code&gt;的&lt;code&gt;SETNX&lt;/code&gt;或者&lt;code&gt;Memcache&lt;/code&gt;的&lt;code&gt;ADD&lt;/code&gt;）去set一个&lt;code&gt;mutex key&lt;/code&gt;，当操作返回成功时，再进行&lt;code&gt;load db&lt;/code&gt;的操作并回设缓存；否则，就重试整个&lt;code&gt;get&lt;/code&gt;缓存的方法。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;SETNX&lt;/code&gt;，是&lt;code&gt;「SET if Not eXists」&lt;/code&gt;的缩写，也就是只有不存在的时候才设置，可以利用它来实现锁的效果。&lt;/p&gt;
&lt;h5 id="2-提前使用互斥锁mutex-key"&gt;2. &amp;ldquo;提前&amp;quot;使用互斥锁(&lt;code&gt;mutex key&lt;/code&gt;)&lt;/h5&gt;
&lt;p&gt;在&lt;code&gt;value&lt;/code&gt;内部设置1个超时值(&lt;code&gt;timeout1&lt;/code&gt;), &lt;code&gt;timeout1&lt;/code&gt;比实际的&lt;code&gt;memcache timeout(timeout2)&lt;/code&gt;小。当从&lt;code&gt;cache&lt;/code&gt;读取到&lt;code&gt;timeout1&lt;/code&gt;发现它已经过期时候，马上延长&lt;code&gt;timeout1&lt;/code&gt;并重新设置到&lt;code&gt;cache&lt;/code&gt;。然后再从数据库加载数据并设置到&lt;code&gt;cache&lt;/code&gt;中。&lt;/p&gt;
&lt;h5 id="3-永远不过期"&gt;3. &amp;ldquo;永远不过期&amp;rdquo;&lt;/h5&gt;
&lt;p&gt;这里的“永远不过期”包含两层意思：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;从&lt;code&gt;redis&lt;/code&gt;上看，确实没有设置过期时间，这就保证了，不会出现热点&lt;code&gt;key&lt;/code&gt;过期问题，也就是“物理”不过期&lt;/li&gt;
&lt;li&gt;从功能上看，如果不过期，那不就成静态的了吗？所以我们把过期时间存在&lt;code&gt;key&lt;/code&gt;对应的&lt;code&gt;value&lt;/code&gt;里，如果发现要过期了，通过一个后台的异步线程进行缓存的构建，也就是“逻辑”过期&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;从实战看，这种方法对于性能非常友好，唯一不足的就是构建缓存时候，其余线程(非构建缓存的线程)可能访问的是老数据，但是对于一般的互联网功能来说这个还是可以忍受。&lt;/p&gt;
&lt;h5 id="4-资源保护"&gt;4. 资源保护&lt;/h5&gt;
&lt;p&gt;采用&lt;code&gt;netflix&lt;/code&gt;的&lt;code&gt;hystrix&lt;/code&gt;，可以做资源的隔离保护主线程池，如果把这个应用到缓存的构建也未尝不可。&lt;/p&gt;
&lt;h4 id="分析"&gt;分析&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left"&gt;解决方案&lt;/th&gt;
&lt;th style="text-align: left"&gt;优点&lt;/th&gt;
&lt;th style="text-align: left"&gt;缺点&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;互斥锁(&lt;code&gt;mutex key&lt;/code&gt;)&lt;/td&gt;
&lt;td style="text-align: left"&gt;思路简单、保证一致性&lt;/td&gt;
&lt;td style="text-align: left"&gt;代码复杂度增大、存在死锁的风险、存在线程池阻塞的风险&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;“提前”使用互斥锁&lt;/td&gt;
&lt;td style="text-align: left"&gt;保证一致性&lt;/td&gt;
&lt;td style="text-align: left"&gt;同上&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;不过期(本文)&lt;/td&gt;
&lt;td style="text-align: left"&gt;异步构建缓存，不会阻塞线程池&lt;/td&gt;
&lt;td style="text-align: left"&gt;不保证一致性、代码复杂度增大、占用一定的内存空间&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;资源隔离组件&lt;code&gt;hystrix&lt;/code&gt;(本文)&lt;/td&gt;
&lt;td style="text-align: left"&gt;&lt;code&gt;hystrix&lt;/code&gt;技术成熟，有效保证后端，&lt;code&gt;hystrix&lt;/code&gt;监控强大。&lt;/td&gt;
&lt;td style="text-align: left"&gt;部分访问存在降级策略。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="总结"&gt;总结&lt;/h3&gt;
&lt;p&gt;针对业务系统，永远都是具体情况具体分析，没有最好，只有最合适。&lt;/p&gt;
&lt;p&gt;最后，对于缓存系统常见的缓存满了和数据丢失问题，需要根据具体业务分析，通常我们采用LRU策略处理溢出，Redis的RDB和AOF持久化策略来保证一定情况下的数据安全。&lt;/p&gt;</description></item><item><title>Twitter-Snowflake算法Scala源码</title><link>https://www.v2ee.top/archives/Twitter-Snowflake%E7%AE%97%E6%B3%95Scala%E6%BA%90%E7%A0%81.html</link><guid isPermaLink="true">https://www.v2ee.top/archives/Twitter-Snowflake%E7%AE%97%E6%B3%95Scala%E6%BA%90%E7%A0%81.html</guid><pubDate>Thu, 06 Sep 2018 17:10:00 +0800</pubDate><description>&lt;h4 id="核心文件"&gt;核心文件&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;/** Copyright 2010-2012 Twitter, Inc.*/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;package&lt;/span&gt; com.twitter.service.snowflake
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; com.twitter.ostrich.stats.Stats
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; com.twitter.service.snowflake.gen._
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; java.util.Random
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; com.twitter.logging.Logger
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * An object that generates IDs.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * This is broken into a separate class in case
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * we ever want to support multiple worker threads
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; * per process
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;IdWorker&lt;/span&gt;(val workerId: Long, val datacenterId: Long, &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; val reporter: Reporter, &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; sequence: Long &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 0L)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;extends&lt;/span&gt; Snowflake.&lt;span style="color:#a6e22e"&gt;Iface&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;&lt;span style="color:#f92672"&gt;]&lt;/span&gt; def &lt;span style="color:#a6e22e"&gt;genCounter&lt;/span&gt;(agent: String) &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Stats.&lt;span style="color:#a6e22e"&gt;incr&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;ids_generated&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Stats.&lt;span style="color:#a6e22e"&gt;incr&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;ids_generated_%s&amp;#34;&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;format&lt;/span&gt;(agent))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;&lt;span style="color:#f92672"&gt;]&lt;/span&gt; val exceptionCounter &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Stats.&lt;span style="color:#a6e22e"&gt;getCounter&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;exceptions&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;&lt;span style="color:#f92672"&gt;]&lt;/span&gt; val log &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Logger.&lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;&lt;span style="color:#f92672"&gt;]&lt;/span&gt; val rand &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; Random
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; val twepoch &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 1288834974657L
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;&lt;span style="color:#f92672"&gt;]&lt;/span&gt; val workerIdBits &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 5L
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;&lt;span style="color:#f92672"&gt;]&lt;/span&gt; val datacenterIdBits &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 5L
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;&lt;span style="color:#f92672"&gt;]&lt;/span&gt; val maxWorkerId &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;1L &lt;span style="color:#f92672"&gt;^&lt;/span&gt; (&lt;span style="color:#f92672"&gt;-&lt;/span&gt;1L &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; workerIdBits)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;&lt;span style="color:#f92672"&gt;]&lt;/span&gt; val maxDatacenterId &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;1L &lt;span style="color:#f92672"&gt;^&lt;/span&gt; (&lt;span style="color:#f92672"&gt;-&lt;/span&gt;1L &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; datacenterIdBits)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;&lt;span style="color:#f92672"&gt;]&lt;/span&gt; val sequenceBits &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 12L
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;&lt;span style="color:#f92672"&gt;]&lt;/span&gt; val workerIdShift &lt;span style="color:#f92672"&gt;=&lt;/span&gt; sequenceBits
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;&lt;span style="color:#f92672"&gt;]&lt;/span&gt; val datacenterIdShift &lt;span style="color:#f92672"&gt;=&lt;/span&gt; sequenceBits &lt;span style="color:#f92672"&gt;+&lt;/span&gt; workerIdBits
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;&lt;span style="color:#f92672"&gt;]&lt;/span&gt; val timestampLeftShift &lt;span style="color:#f92672"&gt;=&lt;/span&gt; sequenceBits &lt;span style="color:#f92672"&gt;+&lt;/span&gt; workerIdBits &lt;span style="color:#f92672"&gt;+&lt;/span&gt; datacenterIdBits
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;&lt;span style="color:#f92672"&gt;]&lt;/span&gt; val sequenceMask &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;1L &lt;span style="color:#f92672"&gt;^&lt;/span&gt; (&lt;span style="color:#f92672"&gt;-&lt;/span&gt;1L &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; sequenceBits)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;private&lt;/span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;&lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; lastTimestamp &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt;1L
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// sanity check for workerId&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (workerId &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; maxWorkerId &lt;span style="color:#f92672"&gt;||&lt;/span&gt; workerId &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; 0) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; exceptionCounter.&lt;span style="color:#a6e22e"&gt;incr&lt;/span&gt;(1)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;throw&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; IllegalArgumentException(&lt;span style="color:#e6db74"&gt;&amp;#34;worker Id can&amp;#39;t be greater than %d or less than 0&amp;#34;&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;format&lt;/span&gt;(maxWorkerId))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (datacenterId &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; maxDatacenterId &lt;span style="color:#f92672"&gt;||&lt;/span&gt; datacenterId &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; 0) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; exceptionCounter.&lt;span style="color:#a6e22e"&gt;incr&lt;/span&gt;(1)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;throw&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; IllegalArgumentException(&lt;span style="color:#e6db74"&gt;&amp;#34;datacenter Id can&amp;#39;t be greater than %d or less than 0&amp;#34;&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;format&lt;/span&gt;(maxDatacenterId))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; log.&lt;span style="color:#a6e22e"&gt;info&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;worker starting. timestamp left shift %d, datacenter id bits %d, worker id bits %d, sequence bits %d, workerid %d&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; timestampLeftShift, datacenterIdBits, workerIdBits, sequenceBits, workerId)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; def &lt;span style="color:#a6e22e"&gt;get_id&lt;/span&gt;(useragent: String): Long &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#f92672"&gt;!&lt;/span&gt;validUseragent(useragent)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; exceptionCounter.&lt;span style="color:#a6e22e"&gt;incr&lt;/span&gt;(1)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;throw&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; InvalidUserAgentError
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; val id &lt;span style="color:#f92672"&gt;=&lt;/span&gt; nextId()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; genCounter(useragent)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; reporter.&lt;span style="color:#a6e22e"&gt;report&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; AuditLogEntry(id, useragent, rand.&lt;span style="color:#a6e22e"&gt;nextLong&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; id
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; def &lt;span style="color:#a6e22e"&gt;get_worker_id&lt;/span&gt;(): Long &lt;span style="color:#f92672"&gt;=&lt;/span&gt; workerId
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; def &lt;span style="color:#a6e22e"&gt;get_datacenter_id&lt;/span&gt;(): Long &lt;span style="color:#f92672"&gt;=&lt;/span&gt; datacenterId
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; def &lt;span style="color:#a6e22e"&gt;get_timestamp&lt;/span&gt;() &lt;span style="color:#f92672"&gt;=&lt;/span&gt; System.&lt;span style="color:#a6e22e"&gt;currentTimeMillis&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;protected&lt;/span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;snowflake&lt;span style="color:#f92672"&gt;]&lt;/span&gt; def &lt;span style="color:#a6e22e"&gt;nextId&lt;/span&gt;(): Long &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;synchronized&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; timestamp &lt;span style="color:#f92672"&gt;=&lt;/span&gt; timeGen()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (timestamp &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; lastTimestamp) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; exceptionCounter.&lt;span style="color:#a6e22e"&gt;incr&lt;/span&gt;(1)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; log.&lt;span style="color:#a6e22e"&gt;error&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;clock is moving backwards. Rejecting requests until %d.&amp;#34;&lt;/span&gt;, lastTimestamp);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;throw&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; InvalidSystemClock(&lt;span style="color:#e6db74"&gt;&amp;#34;Clock moved backwards. Refusing to generate id for %d milliseconds&amp;#34;&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;format&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; lastTimestamp &lt;span style="color:#f92672"&gt;-&lt;/span&gt; timestamp))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (lastTimestamp &lt;span style="color:#f92672"&gt;==&lt;/span&gt; timestamp) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sequence &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (sequence &lt;span style="color:#f92672"&gt;+&lt;/span&gt; 1) &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt; sequenceMask
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;if&lt;/span&gt; (sequence &lt;span style="color:#f92672"&gt;==&lt;/span&gt; 0) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; timestamp &lt;span style="color:#f92672"&gt;=&lt;/span&gt; tilNextMillis(lastTimestamp)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sequence &lt;span style="color:#f92672"&gt;=&lt;/span&gt; 0
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; lastTimestamp &lt;span style="color:#f92672"&gt;=&lt;/span&gt; timestamp
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ((timestamp &lt;span style="color:#f92672"&gt;-&lt;/span&gt; twepoch) &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; timestampLeftShift) &lt;span style="color:#f92672"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (datacenterId &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; datacenterIdShift) &lt;span style="color:#f92672"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (workerId &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; workerIdShift) &lt;span style="color:#f92672"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sequence
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;protected&lt;/span&gt; def &lt;span style="color:#a6e22e"&gt;tilNextMillis&lt;/span&gt;(lastTimestamp: Long): Long &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; timestamp &lt;span style="color:#f92672"&gt;=&lt;/span&gt; timeGen()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; (timestamp &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; lastTimestamp) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; timestamp &lt;span style="color:#f92672"&gt;=&lt;/span&gt; timeGen()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; timestamp
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;protected&lt;/span&gt; def &lt;span style="color:#a6e22e"&gt;timeGen&lt;/span&gt;(): Long &lt;span style="color:#f92672"&gt;=&lt;/span&gt; System.&lt;span style="color:#a6e22e"&gt;currentTimeMillis&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; val AgentParser &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;([a-zA-Z][a-zA-Z\-0-9]*)&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;r&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; def &lt;span style="color:#a6e22e"&gt;validUseragent&lt;/span&gt;(useragent: String): Boolean &lt;span style="color:#f92672"&gt;=&lt;/span&gt; useragent match {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;case&lt;/span&gt; AgentParser(_) &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;case&lt;/span&gt; _ &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="文件下载"&gt;文件下载&lt;/h4&gt;
&lt;p&gt;&lt;a href="https://www.itgas.net/usr/uploads/2018/09/2188549791.zip"&gt;snowflake-snowflake-2010.zip&lt;/a&gt;&lt;/p&gt;</description></item><item><title>MySQL中INT相关类型默认长度</title><link>https://www.v2ee.top/archives/MySQL%E4%B8%ADINT%E7%9B%B8%E5%85%B3%E7%B1%BB%E5%9E%8B%E9%BB%98%E8%AE%A4%E9%95%BF%E5%BA%A6.html</link><guid isPermaLink="true">https://www.v2ee.top/archives/MySQL%E4%B8%ADINT%E7%9B%B8%E5%85%B3%E7%B1%BB%E5%9E%8B%E9%BB%98%E8%AE%A4%E9%95%BF%E5%BA%A6.html</guid><pubDate>Tue, 28 Aug 2018 14:07:00 +0800</pubDate><description>&lt;p&gt;int bigint smallint 和 tinyint 类型，如果创建新表时没有指定 int(M) 中的M时，默认分别是 ：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;int ------- int(11)
bigint ------- bigint(20)
smallint ------- smallint(6)
tinyint ------- tinyint(4)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;下面是这几种类型的取值范围
&lt;img src="https://www.itgas.net/usr/uploads/2018/08/4166085250.jpg" alt="取值范围.jpg"&gt;&lt;/p&gt;
&lt;p&gt;MySQL还支持选择在该类型关键字后面的括号内指定整数值的显示宽度(例如，INT(4))。int(M) 在 integer 数据类型中，M 表示最大显示宽度，该可选显示宽度规定用于显示宽度小于指定的列宽度的值时从左侧填满宽度。显示宽度并不限制可以在列内保存的值的范围，也不限制超过列的指定宽度的值的显示。&lt;/p&gt;
&lt;p&gt;在 int(M) 中，M 的值跟 int(M) 所占多少存储空间并无任何关系。和数字位数也无关系， int(3)、int(4)、int(8) 在磁盘上都是占用 4 btyes 的存储空间。当结合可选扩展属性ZEROFILL使用时， 默认补充的空格用零代替。例如，对于声明为INT(5) ZEROFILL的列，值4检索为00004。bigint 用于某些特殊的情况，当整数值超过 int 数据类型支持的范围时，就可以采用 bigint。&lt;/p&gt;</description></item><item><title>Nginx的五种负载均衡策略</title><link>https://www.v2ee.top/archives/Nginx%E7%9A%84%E4%BA%94%E7%A7%8D%E8%B4%9F%E8%BD%BD%E5%9D%87%E8%A1%A1%E7%AD%96%E7%95%A5.html</link><guid isPermaLink="true">https://www.v2ee.top/archives/Nginx%E7%9A%84%E4%BA%94%E7%A7%8D%E8%B4%9F%E8%BD%BD%E5%9D%87%E8%A1%A1%E7%AD%96%E7%95%A5.html</guid><pubDate>Fri, 17 Aug 2018 19:40:00 +0800</pubDate><description>&lt;p&gt;Nginx可以根据客户端IP进行负载均衡，在upstream里设置ip_hash，就可以针对同一个C类地址段中的客户端选择同一个后端服务器，除非那个后端服务器宕了才会换一个。&lt;/p&gt;
&lt;h4 id="nginx的upstream目前支持的5种方式的分配"&gt;Nginx的upstream目前支持的5种方式的分配&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;1、轮询（默认）​&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;每个请求按时间顺序逐一分配到不同的后端服务器，如果后端服务器down掉，能自动剔除。&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;upstream backserver {
server 192.168.0.14;
server 192.168.0.15;
}
&lt;/code&gt;&lt;/pre&gt;&lt;blockquote&gt;
&lt;p&gt;2、指定权重&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;指定轮询几率，weight和访问比率成正比，用于后端服务器性能不均的情况。&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;upstream backserver {
server 192.168.0.14 weight=10;
server 192.168.0.15 weight=10;
}
&lt;/code&gt;&lt;/pre&gt;&lt;blockquote&gt;
&lt;p&gt;3、ip_hash(ip绑定)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;每个请求按访问ip的hash结果分配，这样每个访客固定访问一个后端服务器，可以解决session的问题。&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;upstream backserver {
ip_hash;
server 192.168.0.14:88;
server 192.168.0.15:80;
}
&lt;/code&gt;&lt;/pre&gt;&lt;blockquote&gt;
&lt;p&gt;4、fair（第三方）&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;按后端服务器的响应时间来分配请求，响应时间短的优先分配。&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;upstream backserver {
server server1;
server server2;
fair;
}
&lt;/code&gt;&lt;/pre&gt;&lt;blockquote&gt;
&lt;p&gt;5、url_hash（第三方）&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;按访问url的hash结果来分配请求，使每个url定向到同一个后端服务器，后端服务器为缓存时比较有效。&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;upstream backserver {
server squid1:3128;
server squid2:3128;
hash $request_uri;
hash_method crc32;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;在需要使用负载均衡的server中增加&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;proxy_pass http://backserver/;
upstream backserver{
ip_hash;
server 127.0.0.1:9090 down; # down 表示当前的server暂时不参与负载
server 127.0.0.1:8080 weight=2; # weight 默认为1.weight越大，负载的权重就越大
server 127.0.0.1:6060;
server 127.0.0.1:7070 backup; # 其它所有的非backup机器down或者忙的时候，请求backup机器
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;max_fails&lt;/code&gt;:允许请求失败的次数默认为1.当超过最大次数时，返回&lt;code&gt;proxy_next_upstream&lt;/code&gt;模块定义的错误
&lt;code&gt;fail_timeout&lt;/code&gt;:&lt;code&gt;max_fails&lt;/code&gt;次失败后，暂停的时间&lt;/p&gt;</description></item></channel></rss>