<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Ruby China 社区 云服务 节点</title>
    <link>https://ruby-china.org/</link>
    <description>Ruby China 社区 云服务 节点最新发帖。</description>
    <item>
      <title>AWS 收费项目如此之多</title>
      <description>&lt;p&gt;公司的项目准备部署在 aws 上，看了一眼 aws 的收费项，简直太多了。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;购买 EC2, 绑定 弹性公网 ip 要收费&lt;/li&gt;
&lt;li&gt;给 EC2 购买一块 EBS，还要按 IO 次数收费，快照也要收费&lt;/li&gt;
&lt;li&gt;购买 RDS, 还要按 IO 收费&lt;/li&gt;
&lt;li&gt;如果买了两台 EC2，两台机器之间的流量也要收费&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;能用的，也就 S3 了。&lt;/p&gt;

&lt;p&gt;想想看，还不如搬瓦工上买一台 vps，各种服务自己搭省钱呢。&lt;/p&gt;

&lt;p&gt;国内的云厂商不是这么收费的，不知道是不是早就算到其他项目中去了。&lt;/p&gt;</description>
      <author>ironboxer</author>
      <pubDate>Tue, 03 Sep 2024 18:58:29 +0800</pubDate>
      <link>https://ruby-china.org/topics/43875</link>
      <guid>https://ruby-china.org/topics/43875</guid>
    </item>
    <item>
      <title>惊！揭露视频网站节约 30% 成本的秘密</title>
      <description>&lt;p&gt;今年，爱奇艺宣布 2022 年第一季度首次实现季度盈利，这是爱奇艺在过去三个季度中，毛利率持续增长，且运营费用持续下降带来的结果。长视频行业发展十几年来，一直深陷亏损旋涡。爱奇艺的首次实现季度盈利，也意味着降本增效将成为视频平台的发展方向。&lt;/p&gt;
&lt;h2 id="视频平台的降本需求"&gt;视频平台的降本需求&lt;/h2&gt;
&lt;p&gt;对于视频网站、App 来说，运营的成本投入主要是由带宽成本、版权成本和推广成本这 3 部分组成，而带宽成本是当前视频网站相当重的一块投入。&lt;/p&gt;

&lt;p&gt;据统计，近年来中国视频云市场高速发展，2020 年中国视频云市场规模达 6955.6 百万美元，较 2019 年增加了 2348.70 百万美元，同比增长 50.98%，未来将继续保持增长，预计 2025 年中国视频云市场规模将达到 31372.1 百万美元。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/upyun/cc1d4c93-9c0f-4150-aa64-41b0c34087dc.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;用户在观看视频的时候，不仅希望能够首屏秒开，全视频流畅观看，对视频清晰度的要求还不断提高，720p 甚至 1080p 清晰度的视频已经满足不了部分用户。国内互联网流量每月消耗 200EB，80% 多的流量消耗来源于视频。这让原本想在带宽成本上节流的视频厂商愁眉不展。&lt;/p&gt;
&lt;h2 id="明眸——降本 30%"&gt;明眸——降本 30%&lt;/h2&gt;
&lt;p&gt;明眸是又拍云基于新型算力生态、边缘计算、低功耗 AI 视频芯片等推出的 AI 视频云产品，通过持续的 AI 训练，在视频客户群体的测试中，能够大幅降低带宽和存储成本 30% 以上，可广泛用于视频内容分发和监控等领域，通过算法来节省 CDN 成本和存储成本。&lt;/p&gt;

&lt;p&gt;又拍云明眸产品针对视频网站的需求与 CDN 技术结合，保证信息高速传输分发。同时 AI 智能还原、画质增强等功能解决视频高清晰度需求，而智能自适应高清低码、极致压缩等技术，大幅降低带宽流量，提升视频观看流畅度。全力支持视频业务发展，再创业务新价值。&lt;/p&gt;

&lt;p&gt;同时，&lt;strong&gt;明眸只需要一键即可开启，秒级接入。&lt;/strong&gt; 无需手动设置视频优化参数，AI 算法可智能识别视频场景，内容自适应调整码率，为客户提供优质的视频优化和加速服务。&lt;/p&gt;
&lt;h3 id="明眸——极速传输"&gt;明眸——极速传输&lt;/h3&gt;
&lt;p&gt;明眸结合又拍云 CDN 产品，保证视频内容的快速分发传输，让视频厂商零成本实现降本增效。&lt;/p&gt;

&lt;p&gt;我们先来简单说下 CDN。CDN（Content Delivery Network），即内容分发网络。当用户访问网站时，CDN 会根据客户端的地区和运营商，将用户分配到距离最近速度最快的节点服务器，让用户以更快的速度获取到所需内容。&lt;/p&gt;

&lt;p&gt;又拍云 CDN 聚焦以下三个特点：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;避让：尽可能避开互联网上可能影响数据传输速度和稳定性的瓶颈和环节，使内容传输得更快、更稳定。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;检测：通过在网络各处放置节点服务器所构成的在现有的互联网基础上的一层智能虚拟网络，CDN 系统能够实时监测网络流量和各节点的连接，负载状况以及到用户的距离和相应时间等综合信息。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;分发：根据监测情况重新导向离用户最近的服务节点上。&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;视频平台使用又拍云 CDN 后，当用户请求访问视频时，又拍云会将视频快速缓存到 CDN 边缘节点上，通过智能调度到客户端最近最优的节点，保证提供视频观看的稳定性和速度。&lt;/p&gt;

&lt;p&gt;明眸与 CDN 相结合，在主动对视频进行压缩后，会将压缩后的视频存到内部存储（非客户存储）。当用户访问该视频 URL，若内部存储存在这个 URL，直接回内部存储请求并在节点缓存。&lt;/p&gt;

&lt;p&gt;依托于 CDN 特性，又拍云明眸还能解决因用户流量持续增长，下载服务器处理能力、服务器出口宽带压力增加而影响的观看体验问题。&lt;/p&gt;
&lt;h3 id="明眸——极致压缩"&gt;明眸——极致压缩&lt;/h3&gt;
&lt;p&gt;在降本这一块，明眸和传统视频提前转码压缩不同，明眸接入了实时访问日志，实时分析用户访问行为以及访问内容频率、内容分类以及用户分布等多种参考因子，根据大数据算法对视频内容进行等级划分，优先将产生高带宽的视频内容交由明眸引擎做优化处理。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/upyun/4904e6f5-fb02-4bf1-b793-998ea4fcd6e5.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;明眸通过将智能场景识别、视觉感知编码、动态编码匹配相结合，实现智能动态编码。针对视频场景、动作、内容、纹理等进行智能分析，综合使用视频处理增强算法和自适应转码算法，来优化视频主观质量并降低编码码率和带宽。明眸的接入只需要一键开启，无需手动设置视频优化参数，AI 算法智能选择最优的转码策略。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/upyun/cfc86369-9227-4891-ac80-94c70edc73ec.png!large" title="" alt=""&gt;&lt;/p&gt;
&lt;h3 id="明眸——智能高清"&gt;明眸——智能高清&lt;/h3&gt;
&lt;p&gt;相比传统视频压缩及传输方案，又拍云明眸所有对于视频的处理都是以不降低人眼感官为前提。&lt;/p&gt;

&lt;p&gt;在不断优化中，又拍云发现人眼对不同场景的感受是不同的，比如一片草地上进行的球赛，人们会更注意赛场上的球员，而对于赛场草地的变化则很少关注。因此明眸将会强化球员区域码率，而相应减少草地区域参数。尽管草地可能会产生一些噪点毛刺等问题，但人眼并不能明显感知。因此又拍云明眸持续不断使用大数据，细分不同画面场景训练明眸视频评价模型，针对不同场景分析当前画面的特征，合理的利用视频编码的特性，可以在更低的码率下，同时保持人眼的感官。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/upyun/39201af0-52be-45ba-a3ff-fc2fb058cac7.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;当然这并不是又拍云明眸的终点，我们会持续加深明眸与 AI 能力的结合，对视频进行更深度的细分优化，持续提升明眸能力，更好的适用于各类场景。&lt;/p&gt;</description>
      <author>upyun</author>
      <pubDate>Thu, 22 Dec 2022 16:30:49 +0800</pubDate>
      <link>https://ruby-china.org/topics/42802</link>
      <guid>https://ruby-china.org/topics/42802</guid>
    </item>
    <item>
      <title>【实操干货】做好这 16 项优化，你的 Linux 操作系统焕然一新</title>
      <description>&lt;p&gt;大家好，这次跟大家谈谈又拍云的操作系统优化方案。往简单地说，我们使用的 Linux 操作系统主要都是基于 CentOS6/7 的精简和优化。往复杂地说，则是我们有两套系统，业务上使用的定制 Linux 系统和数据中心使用的优化版 Linux 系统。&lt;/p&gt;

&lt;p&gt;业务上我们使用裁剪过的定制 Linux 系统，目的是为了更安全、更高效、更加贴近业务需求，方便全国各点进行闪电式部署，但这套系统不具备普适性，所以我们今天暂时不谈它。今天主要分享数据中心常用的 Linux 优化版本，因为这个比较通用，适合大家在使用时进行参考。我会从以下几个方面来进行分享。&lt;/p&gt;
&lt;h2 id="主机名设定和永久生效"&gt;主机名设定和永久生效&lt;/h2&gt;
&lt;p&gt;在 CentOS 或 RHEL 中，有以下三种定义的主机名：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;静态的（static）：“静态”主机名也称为内核主机名，是系统在启动时从 /etc/hostname 自动初始化的主机名。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;瞬态的（transient）：“瞬态”主机名是在系统运行时临时分配的主机名如通过 DHCP 或 mDNS 服务器分配。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;灵活的（pretty）：“灵活”主机名则允许使用自由形式（包括特殊/空白字符）的主机名，以展示给终端用户（如 Gemini's Computer）。&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;好的主机名，可以让非运维的机房人员一目了然地了解和定位机器。比如：用途名 + 省份 + 机房名 + 机柜号 + 编号，示例如下：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HOST="DBS-ZJ-FUD-009"
hostnamectl set-hostname --static $HOST
hostnamectl set-hostname --pretty $HOST
hostnamectl set-hostname --transient  $HOST
echo "$HOST" &amp;gt; /proc/sys/kernel/hostname
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="定制远程登录界面"&gt;定制远程登录界面&lt;/h2&gt;
&lt;p&gt;登陆 Linux 的欢迎界面可由 /etc/issue和/etc/motd 控制。如下显示，不用登录系统就能一目了然的知道系统版本、CPU 和内存型号容量、运行状态、应用版本号及网络连接情况。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/upyun/b719e2fe-caee-45b9-adc6-be60e39fe0cc.png!large" title="" alt=""&gt;&lt;/p&gt;
&lt;h2 id="字符集配置"&gt;字符集配置&lt;/h2&gt;
&lt;p&gt;好的字符集，可以避免终端显示下的乱码。建议使用 en_US.utf8 字符集。&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# 查看操作系统支持的所有字符集
# locale -a

cat &amp;gt; /etc/locale.conf &amp;lt;&amp;lt;EOF
LANG=en_US.utf8
LC_CTYPE=en_US.utf8
EOF
localectl set-locale LANG=en_US.UTF8
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="常规基础软件安装"&gt;常规基础软件安装&lt;/h2&gt;
&lt;p&gt;因为使用的都是基于 CentOS 的最小化精简安装，安装后会缺少一些常规的基础软件，所以我们会适当补充一些基础软件，以帮助快速排查和定位问题。&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yum install -y tree ntpdate  bc nc net-tools wget lsof rsync nmon bash-completion iptables-services firewalld sysstat mtr htop bind-utils yum-utils epel-release smartmontools supervisor python-setuptools python-pip pkgconfig

&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="时区和时间同步设定"&gt;时区和时间同步设定&lt;/h2&gt;
&lt;p&gt;在实际生产环境中，保障服务器时区和时间的一致性非常重要。尤其是分布式系统、多机集群环境、数据库主从备份、以及依赖时间同步的定时任务等场景，时区和时间同步是非常有用的，一旦二者不一致很容易导致各种各样的问题。&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;timedatectl set-timezone Asia/Shanghai
timedatectl set-ntp 1
timedatectl set-local-rtc 0
#timedatectl set-time "2018-08-08 18:08:08"
ntpdate -u cn.pool.ntp.org
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;强烈建议同时把时间同步操作也写入 crontab 里做双保险。&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# crontab -l
0 * * * * root(ntpdate -o3 192.168.1.10 211.115.194.21 )
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="禁用 SELinux"&gt;禁用 SELinux&lt;/h2&gt;
&lt;p&gt;SELinux 为安全增强型 Linux（Security-Enhanced Linux），主要由美国国家安全局开发。它概念严谨、结构及配置复杂、操作严格。因此在使用时可以视情况决定是否要开启使用，可以在有机密和信息敏感机构等的特殊场景下可以启用。&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sed -r -i  '/^SELINUX=/s^=.*^=disabled^g' /etc/selinux/config
set enforce 0
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="添加普通用户并 sudo"&gt;添加普通用户并 sudo&lt;/h2&gt;
&lt;p&gt;sudo 是 Linux 系统管理指令，是允许系统管理员让普通用户执行一些或者全部的 root 命令的一个工具，如 halt、reboot、su 等等。这样不但可以减少 root 用户的登录和管理时间，也能够提高安全性。&lt;/p&gt;

&lt;p&gt;需要注意的是，生产环境尽量不要直接用 root，建议先新建普通用户再提升权限。&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[root@OPS-FDI-020 ~]# useradd shaohy
[root@OPS-FDI-020 ~]# usermod -G wheel  shaohy
[root@OPS-FDI-020 ~]# sed -i '/pam_wheel/s/^#//g'  /etc/pam.d/su
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;为用户 shaohy 添加 sudo，除关机外的其他所有操作：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[root@OPS-FDI-020 ~]# visudo
Cmnd_Alias SHUTDOWN = /sbin/halt, /sbin/shutdown, /sbin/poweroff, /sbin/reboot, /sbin/init
shaohy         ALL=(ALL)       ALL,!SHUTDOWN
%wheel         ALL=(ALL)       ALL,!SHUTDOWN    #修改wheel组的权限，禁止关机
Defaults logfile=/var/log/sudo.log
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="配置防火墙规则和 iptables"&gt;配置防火墙规则和 iptables&lt;/h2&gt;
&lt;p&gt;自 CentOS7 以后都是默认使用 firewalld 管理 netfilter 子系统，需要注意的是底层调用的命令仍然使用了  iptables。二者的区别对比如下：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;firewalld 可以动态修改单条规则，动态管理规则集，允许更新规则而不破坏现有会话和连接。而 iptables，在修改了规则后必须得全部刷新才可以生效。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;firewalld 使用区域和服务而不是链式规则。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;firewalld 默认是拒绝的，需要设置以后才能放行。而 iptables 默认是允许的，需要拒绝的才去限制。&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;所以在选择时可以考虑不拒绝 firewalld，去尝试接受它。&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/sh&lt;/span&gt;
&lt;span class="nv"&gt;IPS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"192.168.0.0/16"&lt;/span&gt;
firewall-cmd &lt;span class="nt"&gt;--zone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;public &lt;span class="nt"&gt;--remove-service&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ssh
firewall-cmd &lt;span class="nt"&gt;--new-zone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;openssh &lt;span class="nt"&gt;--permanent&lt;/span&gt;
firewall-cmd &lt;span class="nt"&gt;--zone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;openssh &lt;span class="nt"&gt;--add-port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;22222/tcp &lt;span class="nt"&gt;--permanent&lt;/span&gt;
firewall-cmd &lt;span class="nt"&gt;--permanent&lt;/span&gt; &lt;span class="nt"&gt;--zone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;public &lt;span class="nt"&gt;--set-target&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;default
&lt;span class="k"&gt;for &lt;/span&gt;ip &lt;span class="k"&gt;in&lt;/span&gt;  &lt;span class="nv"&gt;$IPS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="k"&gt;do
        &lt;/span&gt;firewall-cmd &lt;span class="nt"&gt;--zone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;openssh &lt;span class="nt"&gt;--add-source&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$ip&lt;/span&gt; &lt;span class="nt"&gt;--permanent&lt;/span&gt;
&lt;span class="k"&gt;done
&lt;/span&gt;firewall-cmd &lt;span class="nt"&gt;--reload&lt;/span&gt;
firewall-cmd &lt;span class="nt"&gt;--runtime-to-permanent&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="GPT 分区和分区挂载"&gt;GPT 分区和分区挂载&lt;/h2&gt;
&lt;p&gt;又拍云每一台 CDN 服务器上都有大量硬盘，且不说 4T、6T 这类量比较小的，即便是 10T 的也有 12 块之多，所以需要自动化格式化和划分区这些硬盘的运维操作。&lt;/p&gt;

&lt;p&gt;早期的主引导记录（Master Boot Record，缩写：MBR），又叫做主引导扇区，也就是计算机开机后访问硬盘时所必须要读取的首个扇区，无法支持大于 2T 的硬盘引导。虽然打了补丁的 MBR 也可以支持大于 2T 的分区，但 GPT 已经成为了新的趋势。相比 MBR 而言，GPT 分区方案有以下特点：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;GPT 是 UEFI 标准的一部分（UEFI 是一种个人电脑系统规格，用来定义操作系统与系统固件之间的软件界面，作为 BIOS 的替代方案）。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GPT 分区列表支持最大 128PB（1PB=1024TB）。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;可以定义 128 个分区。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;没有主分区，扩展分区和逻辑分区的概念，所有分区都能格式化。&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/sh&lt;/span&gt;
&lt;span class="nv"&gt;DEV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;lsscsi | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'/HGST/{print $NF}'&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt; &lt;span class="c"&gt;# 筛选所有的sata硬盘&lt;/span&gt;
&lt;span class="nv"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1
&lt;span class="k"&gt;for &lt;/span&gt;dev &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;$DEV&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="k"&gt;do
        &lt;/span&gt;&lt;span class="nv"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/disk/sata0&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$dev&lt;/span&gt; &lt;span class="nv"&gt;$label&lt;/span&gt;
        parted &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nv"&gt;$dev&lt;/span&gt; &lt;span class="nb"&gt;rm &lt;/span&gt;1
        parted &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nv"&gt;$dev&lt;/span&gt; mklabel gpt
        parted &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nv"&gt;$dev&lt;/span&gt; mkpart primary ext4 2048s 100%
        partx &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="nv"&gt;$dev&lt;/span&gt;
        &lt;span class="o"&gt;((&lt;/span&gt;i++&lt;span class="o"&gt;))&lt;/span&gt;
        &lt;span class="nb"&gt;nohup &lt;/span&gt;mkfs.ext4 &lt;span class="nt"&gt;-L&lt;/span&gt; &lt;span class="nv"&gt;$label&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;dev&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;1 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;/dev/null &amp;amp;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="ulimit 配额设定"&gt;ulimit 配额设定&lt;/h2&gt;
&lt;p&gt;因为 CentOS7 / RHEL7 系统中使用 Systemd 替代了之前的 SysV，导致 /etc/security/limits.conf 文件的配置只适用于通过 PAM 认证登录用户的资源限制，对 systemd 的 service 资源限制不生效。&lt;/p&gt;

&lt;p&gt;因为 systemd service 的资源限制，所以我们将全局配置放置于  /etc/systemd/system.conf 和 /etc/systemd/user.conf 中。其中 system.conf 用于系统实例，user.conf 用于用户实例。&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sed -r -i -e '/DefaultLimitCORE/s^.*^DefaultLimitCORE=infinity^g' -e '/DefaultLimitNOFILE/s^.*^DefaultLimitNOFILE=100000^g' -e '/DefaultLimitNPROC/s^.*^DefaultLimitNPROC=100000^g' /etc/systemd/system.conf

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;加大打开文件数的限制，默认设置了非 root 用户的最大进程数为 4096。&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat &amp;gt; /etc/security/limits.d/20-nproc.conf &amp;lt;&amp;lt;EOF
*       soft  nproc  10240
root    soft  nproc  unlimited
EOF
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="sysctl.conf 配置生效"&gt;sysctl.conf 配置生效&lt;/h2&gt;
&lt;p&gt;sysctl.conf 文件配置参数较多且复杂，如果需要详解每一个参数的作用需要很长时间。这里我们之间看一部分常见调优参数来感受一下。主要是集中在网络和 TCP 参数优化、swap 禁用、文件句柄放大。&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
net.ipv4.ip_forward=1
net.ipv4.ip_local_port_range=1000 65535

net.ipv4.tcp_slow_start_after_idle=0
net.ipv4.tcp_no_metrics_save=1
net.ipv4.tcp_rfc1337=1
net.ipv4.tcp_timestamps=1
net.ipv4.tcp_sack=1
net.ipv4.tcp_dsack=1
net.ipv4.tcp_window_scaling=1
net.ipv4.tcp_rmem=4096 102400 16777216
net.ipv4.tcp_wmem=4096 102400 16777216
net.ipv4.tcp_mem=786432 1048576 1572864
net.ipv4.tcp_syncookies=1
net.ipv4.tcp_syn_retries=3
net.ipv4.tcp_synack_retries=5
net.ipv4.tcp_retries1=3
net.ipv4.tcp_retries2=15
net.ipv4.tcp_fin_timeout=30
net.ipv4.tcp_max_syn_backlog=262144                                  
net.ipv4.tcp_max_orphans=262144
net.ipv4.tcp_tw_recycle=0
net.ipv4.tcp_tw_reuse=1
net.ipv4.tcp_keepalive_time=30
net.ipv4.tcp_keepalive_intvl=10
net.ipv4.tcp_keepalive_probes=3
net.ipv4.tcp_max_tw_buckets=600000
net.ipv4.tcp_congestion_control=bbr

net.core.somaxconn=8192
net.core.rmem_default=131072
net.core.wmem_default=131072
net.core.rmem_max=33554432
net.core.wmem_max=33554432
net.core.dev_weight=512
net.core.optmem_max=262144
net.core.netdev_budget=1024
net.core.netdev_max_backlog=262144

vm.swappiness=0
vm.dirty_writeback_centisecs=9000
vm.dirty_expire_centisecs=18000
vm.dirty_background_ratio=5
vm.dirty_ratio=10
vm.overcommit_memory=1
vm.overcommit_ratio=50
vm.max_map_count=200000

fs.file-max=524288
fs.aio-max-nr=1048576 
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="/etc/passwd 安全性检查"&gt;/etc/passwd 安全性检查&lt;/h2&gt;
&lt;p&gt;用户的 shell 权限检查，通常考虑到安全性的问题，不允许有非 root 用户拥有 shell 权限。&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# 过滤出有uid==0, gid==0的潜伏用户,判断有没有bash
awk -F: '($3==0||$4==0) {print $0}' /etc/passwd|grep -i bash
# 除root外的用户shell全部为nologin
sed -r -i '/^[^root]/s:/bin/bash:/sbin/nologin:g' /etc/passwd
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="sshd 服务配置"&gt;sshd 服务配置&lt;/h2&gt;
&lt;p&gt;因为几乎所有 Linux 服务器都通过 SSH 来进行远程管理，这很容易招来许多不速之客，想方设法通过 SSH 来取得您的服务器权限。所以 SSH 安全不容忽视！强烈建议禁用口令登录，修改之前先改用公密钥的方式来 SSH 登录管理服务器。&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sed -r -i '/#Port 22/s^.*^Port 22222^g;/^PasswordAuthentication/s^yes^no^g' /etc/ssh/sshd_config

&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="关闭不必要服务"&gt;关闭不必要服务&lt;/h2&gt;
&lt;p&gt;Linux 服务（Linux services）对于每个应用 Linux 的用户来说都很重要。关闭不必要的服务，可以让 Linux 运行更高效，但并不是所有的 Linux 服务都可以关闭，这个要自己权衡。&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;systemctl disable network  postfix irqbalance tuned rpcbind.target
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果有基于 udp 的服务，如 ntpd、dns，要注意 udp 的反射攻击。因为 udp 的反射攻击破坏力极大，最好关闭掉无用相关的服务，或者选择高防机房去部署此类服务。&lt;/p&gt;
&lt;h2 id="logrotate 缩减轮转日志包"&gt;logrotate 缩减轮转日志包&lt;/h2&gt;
&lt;p&gt;当服务器进程较多，日志文件大小增长较快，就会不断消耗磁盘空间并触发告警。这时就需要人为定期按照各种维度去手动清理日志，如果不及时清理则很容易变成运维事故。&lt;/p&gt;

&lt;p&gt;通常可以使用 logrotate 日志滚动机制将日志文件按时间或大小分成多份，删除时间久远的日志文件，从而节省空间和方便整理。&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sed -r -i 's@weekly@daily@g;s@^rotate.*@rotate 7@g;s@^#compress.*@compress@g' /etc/logrotate.conf
systemctl daemon-reload; systemctl restart rsyslog
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="journalctl 调整 journal 日志"&gt;journalctl 调整 journal 日志&lt;/h2&gt;
&lt;p&gt;在 Systemd 出现之前，Linux 系统及各应用的日志都是分别管理的，而 Systemd 统一管理了所有 Unit 启动日志。这样的好处就是可以只用一个 journalctl 命令，查看所有内核和应用的日志。&lt;/p&gt;

&lt;p&gt;适当的配置可以让 journal 体积可控，不至于容量爆炸。&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sed -r -i -e '/Compress=/s@.*@Compress=yes@g; /SystemMaxUse=/s@.*@SystemMaxUse=4G@g; ' -e '/SystemMaxFileSize=/s@.*@SystemMaxFileSize=256M@g;' -e '/MaxRetentionSec=/s@.*@MaxRetentionSec=2week@g' /etc/systemd/journald.conf
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;综上所述，完成以上这些优化后，一个安全可靠的操作系统就可以正式上线提供服务了，祝大家 Linux 之旅玩得愉快！&lt;/p&gt;
&lt;h3 id="推荐阅读"&gt;推荐阅读&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.upyun.com/tech/article/701/%E9%9D%A2%E8%AF%95%E5%AE%98%E9%97%AE%EF%BC%8CRedis%20%E6%98%AF%E5%8D%95%E7%BA%BF%E7%A8%8B%E8%BF%98%E6%98%AF%E5%A4%9A%E7%BA%BF%E7%A8%8B%E6%88%91%E6%87%B5%E4%BA%86.html" rel="nofollow" target="_blank" title=""&gt;面试官问，Redis 是单线程还是多线程我懵了&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.upyun.com/tech/article/715/Base64%20%E7%BC%96%E7%A0%81%E7%9F%A5%E8%AF%86%EF%BC%8C%E4%B8%80%E6%96%87%E6%89%93%E5%B0%BD%EF%BC%81.html" rel="nofollow" target="_blank" title=""&gt;Base64 编码知识，一文打尽&lt;/a&gt;&lt;/p&gt;</description>
      <author>upyun</author>
      <pubDate>Mon, 13 Jun 2022 10:36:41 +0800</pubDate>
      <link>https://ruby-china.org/topics/42453</link>
      <guid>https://ruby-china.org/topics/42453</guid>
    </item>
    <item>
      <title>解决跨海高并发崩溃难题？so easy</title>
      <description>&lt;p&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;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&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;这些活动很容易吸引非常多的用户，在同一时间段涌入同一个 App 或者页面。这使得短时间内对服务器的并发请求数激增，很容易导致服务器崩溃。我也是在了解这些后，才知道每年我参与秒杀活动失败的真正原因。&lt;/p&gt;
&lt;h2 id="什么是高并发"&gt;什么是高并发&lt;/h2&gt;
&lt;p&gt;了解高并发之前，我们要先知道并发数是什么？并发数是指系统同时能处理的请求数量，这也是反应系统的负载能力的指数之一。&lt;/p&gt;

&lt;p&gt;高并发是指在同一个时间点内出现大量用户请求访问服务器，这些请求其实是 update 修改数据库数据，通常在接到请求后 update 会进行锁表，等待一个请求执行完毕后才能处理下一个请求。而如果客户请求累计的数量超过了数据库链接限制，服务器会返回链接超时。同时请求过多，还会导致同一条数据添加两次，无法保证数据的一致性。&lt;/p&gt;

&lt;p&gt;而跨境业务因为身处全球不同的网络环境、发展程度、运营模式、拥堵程度的场景下，很难针对高并发进行可用性和容错性的性能优化。偏偏跨境业务想要扩展又免不了要面对网站促销、活动并发、临时流量突发的状况。如果你无法智能调控分配带宽，就会让服务负载压力过大，进而影响网络连通性，导致用户流失。&lt;/p&gt;

&lt;p&gt;同时，相较于国内，跨境业务面对恶意攻击的发生概率直线上升，例如 DDoS 攻击就是其中一种。事实上，DDoS 是另一种形式的高并发。面对这种恶性行为，如果自主的服务器和带宽没有一定的防攻击能力，可能会造成大量的用户流失。&lt;/p&gt;

&lt;p&gt;考虑到成本和时间问题，接入云服务商成了不二选择。&lt;/p&gt;
&lt;h2 id="又拍云海外加速"&gt;又拍云海外加速&lt;/h2&gt;
&lt;p&gt;又拍云服务集合分布式架构、大带宽负载均衡网关、OpenStack 虚拟化云处理，打造集松耦合、可弹性扩容、集中资源池化的高效能服务。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/upyun/89a195d9-5d7c-4f7c-9878-24c47052a4b2.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;可用性&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;又拍云担负着庞大数据，对于处理大流量请求有着丰富经验，能够保证提供稳定可靠的高可用服务。&lt;/p&gt;

&lt;p&gt;又拍云采用边缘计算的分布式网络架构，全球 Anycast 网络覆盖 90 个国家，200 多个城市，可以让客户端数据优先选择就近节点进行分析、处理和存储，摒除跨运营商访问的延迟和卡顿，保证数据传输稳定流畅。&lt;/p&gt;

&lt;p&gt;同时边缘节点完成部分处理，也能减轻数据中心集中处理的压力，进一步减少过度访问之类情况的出现，保证服务稳定可用。配合分段缓存预加载功能，能有效降低源站带宽压力，避免因为突发大量请求导致的源站崩溃。&lt;/p&gt;

&lt;p&gt;又拍云海外加速服务同时支持 TLS 1.3，HTTP/2 和 AMP 等最新的 Web 标准，并允许部署自定义 JavaScript，依靠分布式网络架构能够快速将更新同步至全球节点。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;容错性&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;又拍云针对跨境业务对于网关和数据网关的高并发性能需求，进行了针对性的大流量大并发的网关改造。&lt;/p&gt;

&lt;p&gt;同时针对突发性高并发请求，系统每 5 分钟一次进行一次数据采样，根据实时数据自动调度。一旦有服务器出现硬件故障，就会自动识别并剥离出集群，从而保证服务器集群部署负载均衡，不影响用户每一次的实际访问。&lt;/p&gt;

&lt;p&gt;此外考虑到用户源站可能出现的问题，又拍云海外加速提供对应容灾机制，支持用户多个源站地址自主设置主备关系及各自轮询权重，进一步减少因高并发引发的故障问题。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;安全性&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;海外业务发展过程中，经常会面对各类恶意攻击，比如 DDoS 攻击就是攻击方对用户源站发送尽可能多的网络访问请求，形成流量洪流来冲击源站系统。&lt;/p&gt;

&lt;p&gt;针对攻击，又拍云海外加速拥有强大的流量攻击防护能力，除去 T 级别的全网流量调度和清洗外，也支持 TCP、UDP、HTTP/HTTTPS 等多种协议，可防护 SYN Flood、ACK Flood、UDP Flood、CC 等多种类型攻击。&lt;/p&gt;

&lt;p&gt;基于多年网站运维及防护经验，又拍云海外加速提供方式针对性护措施，以保护源站安全和业务的正常访问：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;又拍云 CDN 网络能够隐藏源站地址，避免源站被 DDoS 流量直接攻击，确保源站的访问正常；&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;又拍云安全防护部署了多个高防服务器，具有较强抗攻击、抗干扰、安全性能好的特性，帮助网站直接拒绝 DDoS 攻击；&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;调度平台将攻击流量牵引至就近的清洗节点清洗，并将清洗后的流量回源到服务器，确保正常流量的访问。&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;特有分布式网络架构则也保证了新规则能在 30s 内实现全球同步，针对每一次攻击试试更新专有防御规则，进一步减少攻击带来的站点崩溃，保证正常用户的流畅访问。&lt;/p&gt;
&lt;h3 id="推荐阅读"&gt;推荐阅读&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.upyun.com/tech/article/713/%E8%B7%A8%E5%A2%83%E7%94%B5%E5%95%86%202%20%E5%A4%A7%E6%8A%80%E6%9C%AF%E9%9A%BE%E9%A2%98%EF%BC%8C%E5%88%B0%E5%BA%95%E8%AF%A5%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%EF%BC%9F.html" rel="nofollow" target="_blank" title=""&gt;跨境电商 2 大技术难题，到底该如何解决？&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.upyun.com/tech/article/709/%E6%B8%B8%E6%88%8F%E5%87%BA%E6%B5%B7%E6%B5%AA%E6%BD%AE%E4%B8%8B%EF%BC%8C%E8%BF%99%E4%BA%9B%E6%8A%80%E6%9C%AF%E9%9A%BE%E7%82%B9%E8%AF%A5%E5%A6%82%E4%BD%95%E6%94%BB%E5%85%8B.html" rel="nofollow" target="_blank" title=""&gt;游戏出海浪潮下，这些技术难点该如何攻克&lt;/a&gt;&lt;/p&gt;</description>
      <author>upyun</author>
      <pubDate>Wed, 08 Jun 2022 10:34:29 +0800</pubDate>
      <link>https://ruby-china.org/topics/42442</link>
      <guid>https://ruby-china.org/topics/42442</guid>
    </item>
    <item>
      <title>推荐一下 Linode 云服务，对比 AWS 更易用更便宜。</title>
      <description>&lt;p&gt;&lt;a href="https://www.linode.com/" rel="nofollow" target="_blank"&gt;https://www.linode.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;下图中的 postgresql 和 worker02 都是最小单元的 vm，$5/month, mail 是$10/month, 这三个都是用的 linode&lt;/p&gt;

&lt;p&gt;lightsail 是 AWS 服务，$20/month&lt;/p&gt;

&lt;p&gt;AWS 的监控服务 cloudwatch 需要另外付费，不过 Linode 的 longview 可以免费监控 10 个 client，不仅仅是 Linode 的 vm，同样可以监控 AWS 及其他云服务的 vm。&lt;/p&gt;

&lt;p&gt;lightsail 上面跑 apache2 和 rails，mail 和 worker02 也都跑 rails，然后 lightsail 上的 apache2 做 proxy，loadbalancer 到三个 rails 节点&lt;/p&gt;

&lt;p&gt;同时 lightsail 上还跑一个 solr，提供论坛的全文搜索，目前论坛服务还没开放，还在测试阶段。为什么选择 solr 而没有用 postgresql 的 full text search，是因为本地开发环境用的是 sqlite3，想着是不是可以有一个外挂式的服务，可以支持不同的数据库。目前 solr 看起来比较轻量级，同时 &lt;a href="https://github.com/sunspot/sunspot" rel="nofollow" target="_blank"&gt;https://github.com/sunspot/sunspot&lt;/a&gt; 提供了非常好的 rails 的集成。&lt;/p&gt;

&lt;p&gt;另外 lightsail 和 mail 的 vm 上每天还跑爬虫的定时任务，每天爬虫大概爬取 450 万数据（页面），然后更新 postgresql。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/crazyjacky/2180a06e-e0fd-4b60-866c-368130745979.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;另外，rails 本身的一些 metrics 使用 newrelic，免费版也基本够了，提供各种 traffic 相关的 metrics，还能同时收集三个 rails instances 的 log 到一起，这样对于生产环境查看日志非常方便。
&lt;img src="https://l.ruby-china.com/photo/crazyjacky/2cfb504c-5e4a-45dc-b0d7-8c60d9c33c70.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;各种 events，metrcis 都有现成的图表，非常方便。
&lt;img src="https://l.ruby-china.com/photo/crazyjacky/2410871c-9fee-4844-ab85-2e0e46fb20b7.png!large" title="" alt=""&gt;&lt;/p&gt;</description>
      <author>crazyjacky</author>
      <pubDate>Wed, 18 May 2022 05:15:41 +0800</pubDate>
      <link>https://ruby-china.org/topics/42400</link>
      <guid>https://ruby-china.org/topics/42400</guid>
    </item>
    <item>
      <title>游戏出海浪潮下，这些技术难点该如何攻克</title>
      <description>&lt;p&gt;《App Annie x Google 2021 年移动游戏出海洞察报告》中提到 2021 年上半年最新数据显示，中国游戏开发商在海外游戏市场份额从四年前的 10% 增长到今年的超过 23% ，已超越美国、日本开发商，第一次跃升海外游戏市场份额首位。&lt;/p&gt;

&lt;p&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;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;安全性：DDoS 攻击是当前游戏出海无可避免的主要威胁&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;那如何高效打破这三个壁垒，如何在保证成本的情况下提升效益，就成为了必然的需求。&lt;/p&gt;
&lt;h2 id="延时和丢包"&gt;延时和丢包&lt;/h2&gt;
&lt;p&gt;我们通常所说的网络延迟其实是由两个部分组成的，一个是网络传输造成的时延，另一个是网络设备处理造成的时延。网络传输从字面意义就可以理解，是指有限或无限信号光缆、空气等介质中的传输。因此网络传输的延迟只和光速或电信号的传输速度有关，是用户无法进行人为改变的延迟。设备处理则指的是在接受发信息包进行一系列包括封装、解封装、编码、解码等等操作时所需要经过的设备，经过设备越多，设备吞吐能力越弱，延迟就越大。&lt;/p&gt;

&lt;p&gt;而这种延迟越大，数据包在传输过程中出现的丢失情况就会越多。跨国传输因为区域之间的网络状况、网络环境，发展程度、运营模式、拥堵程度等等问题，在延迟和丢包上都比国内环境要更大。这就让玩家在游玩时容易出现卡顿、掉线的情况，游戏体验大幅下降。特别是一些即时对抗类的游戏，在出现这样的情况后，就可能会造成大量的玩家流失。&lt;/p&gt;
&lt;h2 id="监控"&gt;监控&lt;/h2&gt;
&lt;p&gt;游戏出海并开始投入运行后，对于游戏运行过程的监控是必不可少的。因为只有做好监控才能及时发现并解决问题，这里的监控通常是指服务器监控和数据监控。&lt;/p&gt;

&lt;p&gt;服务器监控又分以下两种：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;机器指标监控：指 CPU、内存、硬盘、网络。其中出海游戏最需要注意的就是网络监控。因为玩家通常来自多个国家，通过使用脚本监控丢包和时延，在异常出现时进行告警通知，能够有效提升用户对游戏的体验，避免造成大型登陆和数据 bug。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;进程、日志监控：进程监控需要监控进程是否正常运作，非正常运作的进程是否完成重启，并对未完成重启的进程进行告警。日志监控一般是对游戏日志进行收集、分析和处理。&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="安全性"&gt;安全性&lt;/h2&gt;
&lt;p&gt;出海的游戏，特别是发行在港台地区的游戏，但凡上榜就会有遭受攻击的可能。而 DDoS 攻击是出海游戏最常见的攻击类型。&lt;/p&gt;

&lt;p&gt;DDoS 攻击是指通过大规模互联网流量淹没目标服务器或其周边基础设施，从而破坏目标服务器、服务或网络正常流量的恶意行为。它利用多台受损计算机系统作为攻击流量来源以达到攻击效果。利用的机器可以包括计算机，也可以包括其他联网资源（如 IoT 设备）。&lt;/p&gt;

&lt;p&gt;通常大家可以选择使用高防产品进行攻击防护，但高防产品的成本较高，而且流量经过高防时会有少量正常用户无可避免地被一块清洗掉。虽然这部分流量并不会很多，但是如果是刚出海的游戏，就会变得明显。当然也可以选择在受到攻击后再接入高防，这样就不用一直支付高防费用，也不用担心用户流量被清洗。可是对接高防是需要进行停服和测试的，如果一款游戏因为攻击而频繁停服测试，无疑也会造成用户的流失。一个完善的防护方案，对于出海游戏也是不得不考虑的存在。&lt;/p&gt;

&lt;p&gt;在云服务逐渐完善的当下，如果出现了一个需要均衡成本和效果的需求，同时这个需求覆盖的内容比较多时。相比自己搭建完善的体系，广大厂商都会更乐意选择接入云服务商。比如又拍云海外加速服务。&lt;/p&gt;
&lt;h2 id="又拍云海外加速"&gt;又拍云海外加速&lt;/h2&gt;
&lt;p&gt;又拍云多年的云服务经验，能够为用户提供包括性能优化、安全保护、边缘平台、实时监控等稳定可靠的各项功能，提供种类丰富的海外加速功能方便用户自由选择，定制适合自己的跨境业务加速方案。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;性能优化&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;又拍云的 DNS 解析速度业界领先，专用海外加速网络内置负载均衡和自动故障转移，在支持每天上百亿的 DNS 查询的同时，先进的集成架构还可以大幅缩减 DNS 解析时间的满足 DNS 的安全防护需求。同时在功能方面支持 TLS 1.3，HTTP/2 和 AMP 等最新的 Web 标准，能够有效帮助出海厂商提升性能效益。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/upyun/a507b773-8f9b-4c38-b171-0d62ee50d395.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;另外还有 5 项特有性能强化，保证无丢包情况下用户端的快速访问：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;边缘计算允许部署自定义 JavaScript 并快速同步至全球节点&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;网页优化：又拍云提供多种前沿的网页优化技术组合&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&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;strong&gt;安全防护&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;基于多年网站运维及防护经验，在跨境业务安全防护方面为用户提供包含 DDoS 及 WAF 在内的稳定快速多种防护模式，新规则 30s 内全球同步。通过分析全球数千万网站流量量，不断主动更新专有防御规则。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/upyun/7920d75b-999b-4889-a9e0-5259b7a073fc.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;而且又拍云首推 CDN 加速服务质量监控平台，实现了服务全透明化监控。日志分析功能统计全服务下的具体访问情况，及时发现丢包数据文件，实时修复减少后续损失。&lt;/p&gt;

&lt;p&gt;海外市场广阔而繁茂，但是其中也藏着不少的困难，选择又拍云，我们一定能够为您的出海业务增添一份助力。&lt;/p&gt;
&lt;h3 id="推荐阅读"&gt;推荐阅读&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.upyun.com/tech/article/705/javaScript%20%E5%86%85%E5%AD%98%E7%AE%A1%E7%90%86%E6%9C%BA%E5%88%B6.html" rel="nofollow" target="_blank" title=""&gt;javaScript 内存管理机制&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.upyun.com/tech/article/707/130%20%E8%A1%8C%E4%BB%A3%E7%A0%81%E6%90%9E%E5%AE%9A%E6%A0%B8%E9%85%B8%E7%BB%9F%E8%AE%A1%EF%BC%8C%E7%A8%8B%E5%BA%8F%E5%91%98%E5%9C%A8%E6%8A%97%E7%96%AB%E6%9C%9F%E9%97%B4%E7%9A%84%E5%A4%A7%E8%83%BD%E9%87%8F.html" rel="nofollow" target="_blank" title=""&gt;130 行代码搞定核酸统计，程序员在抗疫期间的大能量&lt;/a&gt;&lt;/p&gt;</description>
      <author>upyun</author>
      <pubDate>Wed, 27 Apr 2022 14:50:46 +0800</pubDate>
      <link>https://ruby-china.org/topics/42349</link>
      <guid>https://ruby-china.org/topics/42349</guid>
    </item>
    <item>
      <title>AI 视频云 VS 窄带高清，谁是视频时代的宠儿</title>
      <description>&lt;p&gt;随着网络技术的逐渐改善，各类视频消息成为媒体传播的主要选择手段。但其实支撑着视频传播的并不单单是网络技术，还有视频转码与压缩技术。这类技术下分很多，比如曾经被频繁提到的 H.265，比如时下热门的窄带高清，比如与元宇宙密不可分的 AI 视频云，他们都有些什么差别，在选择时我们该选择什么？&lt;/p&gt;
&lt;h2 id="窄带高清"&gt;窄带高清&lt;/h2&gt;
&lt;p&gt;我们通常所说的窄带高清，指的是在视频编码率保持不变的前提下，平均降低视频大小的方法。以又拍云窄带高清为例，其工作大致流程为首先输入一个视频转码的分片，接着进行复杂度分析，然后分场景转码参数，比如运动缓慢还是剧烈，当然这其中还会有码率控制的算法来调整编码器的输出，最终得到编码后的视频。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/upyun/78d1e303-72a7-43be-b810-e8955b064db9.png!large" title="" alt="窄带高清流程简图"&gt;&lt;/p&gt;

&lt;p&gt;这其中的复杂度，又拍云借鉴了标准 BT1788 里的关于空间感知信息和时间感知信息。空间感知信息是每一帧图像做一个 Sobel 值，然后分析它的纹理的多少作为参考标准；时间感知信息是帧与帧之间的帧差做标准差，作为时间上的变化情况。又拍云最初根据用户的应用场景不同一共分了四类场景：手机自拍、动画、运动缓慢和运动剧烈。不需要用户操作，由系统根据复杂度的分析自动选择上面四个最合适的方法。&lt;/p&gt;

&lt;p&gt;而编码器则使用了 H.264 和 H.265 两种。其中 H.265 是在视频编码标准 H.264 基础上，进一步提高压缩效率、提高鲁棒性（Robustness 抗变换性）和错误恢复能力、减少实时的时延、减少信道获取时间和随机接入时延、降低复杂度，以达到最优化设置。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/upyun/91ff157c-3e54-4838-adec-9a301194512d.png!large" title="" alt="H.265 与 H.264 流量比较（资料来源：IEEE）"&gt;&lt;/p&gt;

&lt;p&gt;在窄带高清中二者编码框架差不多，都是关于空间域和时间域的冗余压缩。其中 H.264 的框架流程包括了帧间、帧内的预测、变换、量化、反变换反量化、熵编码和去方块滤波。而 H.265 大致上与 H.264 相同，包括了帧间、帧内的预测、熵编码等，只不过 Deblocking 为了去除“块效应"，增加了一个新的 SAO 的滤波来消除振铃效应。不过虽然框架相同，H.265 在技术上却进行了相关优化：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;H.264 块的尺寸是从 16x16 扩展到 H.265 的 64x64，这是一个指数级的块的复杂度的提升；&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;H.265 帧内的预测方向提升到了 35 种。因为 H.265 是针对高清的，包括 1080P、2K、4K，最高到 8K，这种图片的尺寸会比较大，所以它可以分大块，对于那些变化不明显的大块图像区域，可以用更大的块尺寸，可以在预测环节减少分块带来的复杂计算。对运动矢量也做了优化，并且对亮度和色度差值算法变的更复杂；&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;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/upyun/0568679c-8067-463d-b1f7-603b14e0dd57.png!large" title="" alt="又拍云窄带高清常用参数"&gt;&lt;/p&gt;
&lt;h2 id="AI视频云"&gt;AI 视频云&lt;/h2&gt;
&lt;p&gt;AI 技术的加入，让用户对视频的内容、检索、个性化推荐、等等个性化设置上都有更大的选择和便利。&lt;/p&gt;

&lt;p&gt;AI 视频云通过结合新型算力生态、边缘计算和低功耗 AI 视频芯片等前沿技术，由 AI 进行有效信息的快速提取和构筑，进而减少人力、物力、时间的损耗。&lt;/p&gt;

&lt;p&gt;其中边缘计算让服务的计算能力更接近于用户，它的基本理念是将数据的处理、应用程序的运行，甚至一些功能服务的实现，由中心服务器下放到网络边缘的节点上，从而有效得减小计算系统的延迟，减少数据传输带宽，缓解云计算中心压力，提高可用性，保护数据安全和隐私。&lt;/p&gt;

&lt;p&gt;与上面所提到的窄带高清不同，AI 视频云更致力于打造全生命周期的，云边一体化视频服务。一般会从以下几个方面提供服务：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;快速产出视频：提供视频录制、编辑、播放为一体的内容生产解决方案。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;完美兼容不同格式、时间的数据：针对大数据和物联网背景下的数据存储需求，提供非结构化数据云存储 USS、融合云存储等对象存储服务。同时提供快速迁移服务，避免用户被数据所困，帮助用户掌握数据主权。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;对于海量数据进行智能分析：基于新型算力生态、边缘计算和低功耗 AI 视频芯片等前沿技术，对 AI 算法进行持续训练，让 AI 形成对特定场景的视频理解能力和视频结构化分析能力。有效且快速地提取有价值的结构信息，免除大量人力、物力和时间的损耗&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;降低成本，提升效率：针对多媒体数据，能有效降低 40-70% 视频大小，同时提供智能视频还原等多种前沿技术。让用户不再需要自建服务和功能，随需随用，大幅降低开发成本。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;避免运营商差异，完成快速分发：依托云服务商大量的节点分部，覆盖全部运营商，同时提供智能调度和边缘缓存功能。能针对应用内容快速分发，提高网站响应速度。&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;那么 AI 视频云和窄带高清又有什么差别呢？&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/upyun/acff02bc-5d39-46d5-9fca-0379d9f2f06c.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;相比窄带高清，AI 视频云的使用更加方便，使用也能更加贴合用户场景。依托于 AI 的智能特性，AI 视频云会不断进行自动调整，不会出现更新换代的问题。&lt;/p&gt;
&lt;h4 id="推荐阅读"&gt;推荐阅读&lt;/h4&gt;
&lt;p&gt;&lt;a href="https://www.upyun.com/tech/article/699/%E8%87%AA%E5%AA%92%E4%BD%93%E6%97%B6%E4%BB%A3%E7%9A%84%E8%B4%A4%E5%86%85%E5%8A%A9%E2%80%94%E2%80%94AI%20%E8%A7%86%E9%A2%91%E4%BA%91.html" rel="nofollow" target="_blank" title=""&gt;自媒体时代的贤内助——AI 视频云&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.upyun.com/tech/article/700/%E5%A6%82%E4%BD%95%E5%A4%84%E7%90%86%E5%A4%A7%E4%BD%93%E7%A7%AF%20XLSX%2FCSV%2FTXT%20%E6%96%87%E4%BB%B6%EF%BC%9F.html" rel="nofollow" target="_blank" title=""&gt;如何处理大体积 XLSX/CSV/TXT 文件？&lt;/a&gt;&lt;/p&gt;</description>
      <author>upyun</author>
      <pubDate>Thu, 21 Apr 2022 11:01:46 +0800</pubDate>
      <link>https://ruby-china.org/topics/42331</link>
      <guid>https://ruby-china.org/topics/42331</guid>
    </item>
    <item>
      <title>如何处理大体积 XLSX/CSV/TXT 文件？</title>
      <description>&lt;p&gt;在开发过程中，可能会遇到这样的需求，我们需要从本地的 Excel 或 CSV 等文件中解析出信息，这些信息可能是考勤打卡记录，可能是日历信息，也可能是近期账单流水。但是它们共同的特点是数据多且繁杂，人工录入的工作量庞大容易出错，需要花费大量时间。那有没有什么方法能自动解析文件并获取有用信息呢？&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/upyun/86607ada-c45a-4802-91f6-979dcbfed7ab.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;当这个文件数据量也不是很多的时候，有很多前端工具可供选择。例如&amp;nbsp;SheetJS，就提供了从&amp;nbsp;Excel、CSV&amp;nbsp;中解析出用信息的很多方法，十分方便。&lt;/p&gt;

&lt;p&gt;当数据量只是几千条的程度的，选择的余地很多，但是一旦数据量级增加，处理就变得复杂。如果&amp;nbsp;XLSX/CSV&amp;nbsp;数据量达到了 100w+ 条，Office、WPS 想打开看一下，都会需要很长的时间。&lt;/p&gt;

&lt;p&gt;那又该如何从这样大体积的&amp;nbsp;Excel/CSV/TXT 中解析出数据呢？&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;背景&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;下面我们通过一个假设的需求，来讲述理解整个过程。假设我们需求是从本地 Excel、CSV、TXT（或者其他格式的）文件中解析出数据，并经过清洗后存入本地数据库文件中。但是这些文件体积可能是 5M、50M、500M 甚至更大。那么在浏览器环境下如何上传？Node 环境下应该如何解析？&lt;/p&gt;

&lt;p&gt;首先，我们需要了解的是浏览器 Web 页面如何上传大体积文件？&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Web 页面如何上传大体积文件？&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Web 页面一般也是可以上传大文件的，但是会面临一个问题。&lt;strong&gt;如果要上传的数据比较大，那么整个上传过程会比较漫长，再加上上传过程的不确定因素，一旦失败，那整个上传就要从头再来，耗时很长。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;面对这个问题，我们可以通过将大文件分成多份小文件，每一次只上传一份的方法来解决。这样即使某个请求失败了，也无需从头开始，只要重新上传失败的那一份就好了。&lt;/p&gt;

&lt;p&gt;如果想要使用这个方法，我们需要满足以下几项需求：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  大体积文件支持切片上传&lt;/li&gt;
&lt;li&gt;  可以断点续传&lt;/li&gt;
&lt;li&gt;  可以得知上传进度&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;首先看一下如何进行大文件切割。Web 页面基本都是通过&amp;nbsp;&amp;nbsp;来获取本地文件的。&amp;nbsp;而通过 input 的&amp;nbsp;event.target.files&amp;nbsp;获取到的 file，其实是一个&amp;nbsp;File&amp;nbsp;类的实例，是&amp;nbsp;Blob&amp;nbsp;类的子类。&lt;/p&gt;

&lt;p&gt;Blob&amp;nbsp;对象表示一个不可变、原始数据的类文件对象。它的数据可以按文本或二进制的格式进行读取，也可以转换成&amp;nbsp;ReadableStream&amp;nbsp;来用于数据操作。&amp;nbsp;简单理解合一将&amp;nbsp;Blob&amp;nbsp;&amp;nbsp;看做二进制容器，表示存放着一个大的二进制文件。Blob 对象有一个很重要的方法：slice()，这里需要注意的是 Blob 对象是不可变的，slice 方法返回的是一个新的 Blob，表示所需要切割的二进制文件。&lt;/p&gt;

&lt;p&gt;slice() 方法接受三个参数，起始偏移量，结束偏移量，还有可选的 mime 类型。如果 mime 类型，没有设置，那么新的 Blob 对象的 mime 类型和父级一样。而 File 接口基于 Blob，File 对象也包含了 slice 方法，其结果包含有源 Blob 对象中指定范围的数据。&lt;/p&gt;

&lt;p&gt;看完了切割的方法，我们就可以对二进制文件进行拆分了。拆分示例如下：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function sliceInPiece(file, piece = 1024 * 1024 * 5) {
  let totalSize = file.size; // 文件总大小
  let start = 0; // 每次上传的开始字节
  let end = start + piece; // 每次上传的结尾字节
  let chunks = []
  while (start &amp;lt; totalSize) {
    // 根据长度截取每次需要上传的数据
    // File对象继承自Blob对象，因此包含slice方法
    let blob = file.slice(start, end); 
    chunks.push(blob)

    start = end;
    end = start + piece;
  }
  return chunks
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;获得文件切割后的数组后，就可以挨个调用接口上传至服务端。&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
let file =  document.querySelector("[name=file]").files[0];

const LENGTH = 1024 * 1024 * 0.1;
let chunks = sliceInPiece(file, LENGTH); // 首先拆分切片

chunks.forEach(chunk=&amp;gt;{
  let fd = new FormData();
  fd.append("file", chunk);
  post('/upload', fd)
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;完成上传后再至服务端将切片文件拼接成完整文件，让 FileReader 对象从 Blob 中读取数据。&lt;/p&gt;

&lt;p&gt;当然这里会遇到两个问题，其一是面对上传完成的一堆切片文件，服务端要如知道它们的正确顺序？其二是如果有多个大体积文件同时上传，服务端该如何判断哪个切片属于哪个文件呢？&lt;/p&gt;

&lt;p&gt;前后顺序的问题，我们可以通过构造切片的 FormData 时增加参数的方式来处理。比如用参数&amp;nbsp;ChunkIndex&amp;nbsp;表示当前切片的顺序。&lt;/p&gt;

&lt;p&gt;而第二个问题可以通过增加参数比如&amp;nbsp;sourceFile&amp;nbsp;等（值可以是当前大体积文件的完整路径或者更严谨用文件的 hash 值）来标记原始文件来源。这样服务端在获取到数据时，就可以知道哪些切片来自哪个文件以及切片之间的前后顺序。&lt;/p&gt;

&lt;p&gt;如果暂时不方便自行构架，也可以考虑使用云服务，比如又拍云存储就支持大文件上传和断点续传的。比如：&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;断点续传&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;在上传大文件或移动端上传文件时，因为网络质量、传输时间过长等原因造成上传失败，可以使用断点续传。特别地，断点续传上传的图片不支持预处理。特别地，断点续传上传的文件不能使用其他上传方式覆盖，如果需要覆盖，须先删除文件。&lt;/p&gt;

&lt;p&gt;\&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;名称概念&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  文件分块：直接切分二进制文件成小块。分块大小固定为 1M。最后一个分块除外。&lt;/li&gt;
&lt;li&gt;  上传阶段：使用 x-upyun-multi-stage 参数来指示断点续传的阶段。分为以下三个阶段：initate(上传初始化), upload(上传中), complete(上传结束)。各阶段依次进行。&lt;/li&gt;
&lt;li&gt;  分片序号：使用 x-upyun-part-id 参数来指示当前的分片序号，序号从 0 起算。&lt;/li&gt;
&lt;li&gt;  顺序上传：对于同一个断点续传任务，只支持顺序上传。&lt;/li&gt;
&lt;li&gt;  上传标识：使用 x-upyun-multi-uuid 参数来唯一标识一次上传任务，类型为字符串，长度为 36 位。&lt;/li&gt;
&lt;li&gt;  上传清理：断点续传未完成的文件，会保存 24 小时，超过后，文件会被删除。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;可以看到，云存储通过分片序号&amp;nbsp;&lt;strong&gt;x-upyun-part-id&lt;/strong&gt;&amp;nbsp;和上传标识&amp;nbsp;&lt;strong&gt;x-upyun-multi-uuid&lt;/strong&gt;&amp;nbsp;解决了我们前面提到的两个问题。这里需要注意的是这两个数据不是前端自己生成的，而是在初始化上传后通过 responseHeader 返回的。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/upyun/94fd37f3-0922-4040-b0aa-2e883ab40089.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;前文说的都是使用 Web 页面要如何上传大文件。接下来我们来看看 NodeJS 是如何解析、处理这类大体积文件呢？&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NodeJS 解析大体积文件&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;首先需要明确一个概念 NodeJS 里没有 File 对象，但是有 fs（文件系统) 模块。fs 模块支持标准 POSIX 函数建模的方式与文件系统进行交互。\&lt;/p&gt;

&lt;p&gt;POSIX 是&lt;strong&gt;可移植操作系统接口&amp;nbsp;Portable Operating System Interface of UNIX&lt;/strong&gt; 的缩写。简单来说 POSIX 就是在不同内核提供的操作系统下提供一个统一的调用接口，比如在 linux 下打开文件和在 widnows 下打开文件。可能内核提供的方式是不同的，但是因为 fs 是支持 POSIX 标准的，因此对程序猿来说无论内核提供的是什么，直接在 Node 里调&amp;nbsp;fsPromises.open(path, flags[, mode])&amp;nbsp;方法就可以使用。&lt;/p&gt;

&lt;p&gt;这里简单用 Vue 举例说明。Vue 在不同的环境下比如 Web 页面或 Weex 等等的运行生成页面元素的方式是不同的。比如在 Web 下的 createElement 是下方这样：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
export function createElement (tagName: string, vnode: VNode): Element {
  const elm = document.createElement(tagName)
  if (tagName !== 'select') {
    return elm
  }
  // false or null will remove the attribute but undefined will not
  if (vnode.data &amp;amp;&amp;amp; vnode.data.attrs &amp;amp;&amp;amp; vnode.data.attrs.multiple !== undefined) {
    elm.setAttribute('multiple', 'multiple')
  }
  return elm
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在 Weex 下则是如下情况：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export function createElement (tagName: string): WeexElement {
  return document.createElement(tagName)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以上两种情况下的&amp;nbsp;&lt;strong&gt;createElement&lt;/strong&gt; 是不一样的。同理，还有很多其他的创建模块或者元素的方式也是不同的，但是针对不同平台，Vue 提供了相同的 patch 方法，来进行组件的更新或者创建。&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import&amp;nbsp;*&amp;nbsp;as&amp;nbsp;nodeOps&amp;nbsp;from&amp;nbsp;'web/runtime![]()de-ops'\
import&amp;nbsp;{&amp;nbsp;createPatchFunction&amp;nbsp;}&amp;nbsp;from&amp;nbsp;'core![]()dom/patch'\
import&amp;nbsp;baseModules&amp;nbsp;from&amp;nbsp;'core![]()dom/modules/index'\
import&amp;nbsp;platformModules&amp;nbsp;from&amp;nbsp;'web/runtime/modules/index'\
\
//&amp;nbsp;the&amp;nbsp;directive&amp;nbsp;module&amp;nbsp;should&amp;nbsp;be&amp;nbsp;applied&amp;nbsp;last,&amp;nbsp;after&amp;nbsp;all\
//&amp;nbsp;built-in&amp;nbsp;modules&amp;nbsp;have&amp;nbsp;been&amp;nbsp;applied.\
const&amp;nbsp;modules&amp;nbsp;=&amp;nbsp;platformModules.concat(baseModules)\
\
//&amp;nbsp;nodeops&amp;nbsp;封装了一系列DOM操作方法。modules定义了一些模块的钩子函数的实现\
export&amp;nbsp;const&amp;nbsp;patch:&amp;nbsp;Function&amp;nbsp;=&amp;nbsp;createPatchFunction({&amp;nbsp;nodeOps,&amp;nbsp;modules&amp;nbsp;})
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import&amp;nbsp;*&amp;nbsp;as&amp;nbsp;nodeOps&amp;nbsp;from&amp;nbsp;'weex/runtime![]()de-ops'\
import&amp;nbsp;{&amp;nbsp;createPatchFunction&amp;nbsp;}&amp;nbsp;from&amp;nbsp;'core![]()dom/patch'\
import&amp;nbsp;baseModules&amp;nbsp;from&amp;nbsp;'core![]()dom/modules/index'\
import&amp;nbsp;platformModules&amp;nbsp;from&amp;nbsp;'weex/runtime/modules/index'\
\
//&amp;nbsp;the&amp;nbsp;directive&amp;nbsp;module&amp;nbsp;should&amp;nbsp;be&amp;nbsp;applied&amp;nbsp;last,&amp;nbsp;after&amp;nbsp;all\
//&amp;nbsp;built-in&amp;nbsp;modules&amp;nbsp;have&amp;nbsp;been&amp;nbsp;applied.\
const&amp;nbsp;modules&amp;nbsp;=&amp;nbsp;platformModules.concat(baseModules)\
\
export&amp;nbsp;const&amp;nbsp;patch:&amp;nbsp;Function&amp;nbsp;=&amp;nbsp;createPatchFunction({\
&amp;nbsp;&amp;nbsp;nodeOps,\
&amp;nbsp;&amp;nbsp;modules,\
&amp;nbsp;&amp;nbsp;LONG_LIST_THRESHOLD:&amp;nbsp;10\
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样，无论运行环境的内部实现是否不同，只要调用相同的 patch 方法即可。而&amp;nbsp;POSIX 的理念是与上面所举例的情况是相通的。&lt;/p&gt;

&lt;p&gt;简单了解了 POSIX，我们回到 fs 模块。fs 模块提供了很多读取文件的方法，例如：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  fs.read(fd, buffer, offset, length, position, callback) 读取文件数据。要操作文件，得先打开文件，这个方法的 fd，就是调用 fs.open&amp;nbsp;返回的文件描述符。&lt;/li&gt;
&lt;li&gt;  fs.readFile(path[, options], callback)&amp;nbsp;异步地读取文件的全部内容。可以看做是 fs.read 的进一步封装。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;使用场景如下：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { readFile } from 'fs';

readFile('/etc/passwd','utf-8', (err, data) =&amp;gt; {
  if (err) throw err;
  console.log(data);
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;因为 fs.readFile 函数会缓冲整个文件，如果要读取的文件体积较小还好，但是如果文件体积较大就会给内存造成压力。那有没有对内存压力较小的方式来读取文件呢？&lt;/p&gt;

&lt;p&gt;有的，我们今天的主角 stream 流登场。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;stream&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;stream 流是用于在 Node.js 中处理流数据的抽象接口。&amp;nbsp;stream 模块提供了用于实现流接口的 API。流可以是可读的、可写的、或两者兼而有之。&lt;/p&gt;

&lt;p&gt;fs 模块内有个 fs.createReadStream(path[, options]) 方法，它返回的是一个可读流，默认大小为 64k，也就是缓冲 64k。一旦内部读取缓冲区达到这个阈值，流将暂时停止从底层资源读取数据，直到消费当前缓冲的数据。&lt;/p&gt;

&lt;p&gt;消费数据的方法可以是调&amp;nbsp;pipe()&amp;nbsp;方法，也可以被事件直接消费。&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// pipe 消费
readable.pipe(writable)

// 或者
// 事件消费
readable.on('data', (chunk) =&amp;gt; {
  writable.write(chunk);
});
readable.on('end', () =&amp;gt; {
  writable.end();
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;除了可读流，也有可写流&amp;nbsp;fs.createWriteStream(path[, options])，可以将数据写入文件中。&lt;/p&gt;

&lt;p&gt;好了，所需要的前置知识基本就介绍完毕了，回到正题。假如我们有一个文件夹，里面存放着数十个 XLSX/CSV&amp;nbsp;文件，且每一个体积都超过了 500M。那该如何从这些文件中读取信息，并写入数据库文件中呢？&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;批量解析&amp;nbsp;CSV&amp;nbsp;文件&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;假设我们需要解析的文件路径已经是知道的，可以通过路径获取到文件，那么将这些路径存入一个数组并命名为&amp;nbsp;needParseArr，我们需要按照顺序一个个解析这些&amp;nbsp; CSV、XLSX 文件信息，并清洗然后写入数据库。&lt;/p&gt;

&lt;p&gt;首先，是一个个读的逻辑 (readOneByOne)。&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async readOneByOne () {
   try {
    for (let i = 0; i &amp;lt; needParsePathArr.length; i++) {
      const filePath = needParsePathArr[i]
      console.log(`解析到第${i}个文件，文件名：${filePath}`)
      await streamInsertDB(filePath)
    }
  } catch (err) {

  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;streamInsertDB 是我们的主要逻辑的入口。&lt;/p&gt;
&lt;pre class="highlight hack"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;streamInsertDB&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="no"&gt;ext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;extname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;// 判断了下文件类型&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ext&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s1"&gt;'.csv'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// 解析csv&lt;/span&gt;
      &lt;span class="nf"&gt;parseAndInsertFromCSV&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ext&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s1"&gt;'.xlsx'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// 自执行函数&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;getName&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;// 先转换成csv。也可以不转换，直接解析xlsx，后文会详细解释。&lt;/span&gt;
          &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="no"&gt;csvFileName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;convertXlsx2Csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filePath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="c1"&gt;// 复用解析csv的逻辑&lt;/span&gt;
          &lt;span class="nf"&gt;parseAndInsertFromCSV&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;csvFileName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nf"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sb"&gt;`error: ${error.message || error}`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;})()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;parseAndInsertFromCSV 中就是使用我们前面所提到的知识点的主要阵地。&lt;/strong&gt; 下面简单介绍一下各个函数：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  chardet：这个函数的作用是监测&amp;nbsp;CSV&amp;nbsp;文件的编码格式的，毕竟不是每个&amp;nbsp;CSV&amp;nbsp;都是 UTF-8 编码，带中文的&amp;nbsp;CSV&amp;nbsp;编码类型可能是 GBK 或者 GB18030、GB18031 等等，这种格式不经过处理直接读取，中文会显示为乱码。所以需要执行转换的函数&amp;nbsp;iconv&amp;nbsp;转换一下。&lt;/li&gt;
&lt;li&gt;  pipe：可以用来建立管道链，可以理解为 pipe 的作用就像一个管道，可以对目标流边读边写，这里我们是一边解码一边重新编码。&lt;/li&gt;
&lt;li&gt;  insertInBlock：这个函数是获取到一定数量的数据后（本例中是从&amp;nbsp;CSV&amp;nbsp;中解析出 3 万条左右数据的时候），暂停一下来执行一些操作，比如写入数据库或者对里面的数据进行过滤、处理等等，根据实际需要来定。&lt;/li&gt;
&lt;li&gt;  csv：这个函数的作用就是读出流中的具体数据的。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;具体逻辑解释可以看注释。&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const chardet = require('chardet');
const csv = require('fast-csv'); // 比较快解析csv的速度的工具
const iconv = require('iconv-lite');

const arrayFromParseCSV = []  // 存放解析出来的一行行csv数据的
let count = 0 // 计数
// resolve, reject 是外部函数传进来的，用以判断函数执行的状态，以便正确的进行后续逻辑处理
function parseAndInsertFromCSV (filePath, resolve, reject) {
  const rs = fs.createReadStream(filePath)  // 创建可读流
  // 这里的防抖和柯里化
  const delayInsert = debounce((isEnd, cb = () =&amp;gt; {}) =&amp;gt; insertInBlock(isEnd, cb, rs, resolve, reject), 300)
  /// sampleSize: 5120 表示值读取文件前5120个字节的数据，就可以判断出文件的编码类型了，不需要全部读取
  chardet.detectFile(filePath, { sampleSize: 5120 }).then(encoding =&amp;gt; {
    // 如果不是UTF-8编码，转换为utf8编码
    if (encoding !== 'UTF-8') {
      rs.pipe(iconv.decodeStream(encoding))
        .pipe(iconv.encodeStream('UTF-8'))
        .pipe(csv.parse({ header: false, ignoreEmpty: true, trim: true })) // 解析csv
        .on('error', error =&amp;gt; {
          reject(`解析csv error: ${error}`)
        })
        .on('data', rows =&amp;gt; {
          count++ // 计数，因为我们要分块读取和操作
          arrayFromParseCSV.push(rows) // 读到就推送到数组中
          if (count &amp;gt; 30000) { // 已经读了30000行，我们就要先把这3w行处理掉，避免占用过多内存。
            rs.pause() // 暂停可读流
            delayInsert(false) // false 还没有结束。注意：即使rs.pause, 流的读取也不是立即暂停的，所以需要防抖。
          }          
        }).on('end', rowCount =&amp;gt; {
          console.log(`解析完${filePath}文件一共${rowCount}行`)
          delayInsert(true, () =&amp;gt; {
            rs.destroy() // 销毁流
            resolve('ok') // 一个文件读取完毕了
          })
        })
    }
  })
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;清洗数据和后续操作的逻辑在 insertInBlock 里。&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function insertInBlock (isEnd, cb, filePath, resolve, reject) {
  const arr = doSomethingWithData() // 可能会有一些清洗数据的操作
  // 假如我们后续的需求是将数据写入数据库
  const batchInsert = () =&amp;gt; {
    batchInsertDatabasePromise().then(() =&amp;gt; {
      if (cb &amp;amp;&amp;amp; typeof cb === 'function') cb()
      !isEnd &amp;amp;&amp;amp; rs.resume() // 这一个片段的数据写入完毕，可以恢复流继续读了
    })
  }

  const truely = schemaHasTable() // 比如判断数据库中有没有某个表，有就写入。没有先建表再写入。
  if (truely) { //
     batchInsert()
   } else {
     // 建表或者其他操作，然后再写入
     doSomething().then(() =&amp;gt; batchInsert())
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样，解析和写入的流程就完成了。虽然很多业务上的代码进行了简略，但实现上大体类似这个流程。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;批量解析&amp;nbsp;XLSX&amp;nbsp;文件&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;转化成&amp;nbsp;CSV？&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;在前面的代码实例中，我们利用了利用可写流 fs.createWriteStream 将&amp;nbsp;XLSX&amp;nbsp;文件转换成 CSV 文件然后复用解析 CSV。这里需要注意的是，在将数据写入 CSV 格式文件时，要在最开始写入 bom 头 \ufeff。此外也可以用 xlsx-extract 的 convert 函数，将 XLSX 文件转换成 TSV。&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
const { XLSX } = require('xlsx-extract')
new XLSX().convert('path/to/file.xlsx', 'path/to/destfile.tsv')
    .on('error', function (err) {
        console.error(err);
    })
    .on('end', function () {
        console.log('written');
    })
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;可能有人会疑惑，不是&amp;nbsp;CSV&amp;nbsp;么，怎么转换成了 TSV 呢？&lt;/p&gt;

&lt;p&gt;其实 tsv 和&amp;nbsp;CSV&amp;nbsp;的区别只是字段值的分隔符不同，CSV 用逗号分隔值（Comma-separated values），而 TSVA 用的是制表符分隔值（Tab-separated values）。前面我们用来快速解析&amp;nbsp;CSV&amp;nbsp;文件的 fast-csv 工具是支持选择制表符\t作为值的分隔标志的。&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { parse } from '@fast-csv/parse';
const stream = parse({ delimiter: '\t' })
    .on('error', error =&amp;gt; console.error(error))
    .on('data', row =&amp;gt; console.log(row))
    .on('end', (rowCount: number) =&amp;gt; console.log(`Parsed ${rowCount} rows`));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;直接解析？&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;那是否可以不转换成 CSV，直接解析 XLSX 文件呢？其实也是可行的。&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const { xslx } = require('xlsx-extract') // 流式解析xlsx文件工具
// parser: expat, 需要额外安装node-expat,可以提高解析速度。
new XLSX().extract(filePath, { sheet_nr: 1, parser: 'expat' })
    .on('row', function (row) {
        // 每一行数据获取到时都可以触发
      }).on('error', function (err) {
        // error
     });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;但是这种方式有一个缺陷，一旦解析开始，就无法暂停数据读取的流程。xlsx-extract 封装了 sax，没有提供暂停和继续的方法。&lt;/p&gt;

&lt;p&gt;如果我们直接用可读流去读取&amp;nbsp;XLSX&amp;nbsp;文件会怎么样呢？&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const readStream = fs.createReadableStream('path/to/xlsx.xlsx')
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;可以看到现在流中数据以 buffer 的形式存在着。但由于 xlsx 格式实际上是一个 zip 存档的压缩格式，存放着 XML 结构的文本信息。所以可读流无法直接使用，需要先解压缩。&lt;/p&gt;

&lt;p&gt;解压缩可以使用 npm 包 unzipper。&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
const unzip = require('unzipper')
const zip = unzip.Parse();
rs.pipe(zip)
  .on('entry', function (entry) {
    console.log('entry ---', entry);
    const fileName = entry.path;
    const { type } = entry; // 'Directory' or 'File'
    const size = entry.vars.uncompressedSize; // There is also compressedSize;
    if (fileName === "this IS the file I'm looking for") {
      entry.pipe(fs.createWriteStream('output/path'));
    } else {
      entry.autodrain();
    }
  })
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;现在我们已经解压了文件。&lt;/p&gt;

&lt;p&gt;前面提到，xlsx-extract 是 封装了 sax，而 sax 本身就是用来解析 XML 文本的，那我们这里也可以使用 sax 来对可读流进行处理。&lt;/p&gt;

&lt;p&gt;sax 解析的源码可以看这里，大致是根据每一个字符来判断其内容、换行、开始、结束等等，然后触发对应事件。&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const saxStream = require('sax').createStream(false);
saxStream.on('error', function (e) {
  console.error('error!', e);
});
saxStream.on('opentag', function (node) {
  console.log('node ---', node);
});
saxStream.on('text', (text) =&amp;gt; console.log('text ---', typeof text, text));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;最后将两者结合起来：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const unzip = require('unzipper');
const saxStream = require('sax').createStream(false);
const zip = unzip.Parse();

saxStream.on('error', function (e) {
  console.error('error!', e);
});
saxStream.on('opentag', function (node) {
  console.log('node ---', node);
});
saxStream.on('text', (text) =&amp;gt; {
    console.log('text ---', typeof text, text)
});

rs.pipe(zip)
  .on('entry', function (entry) {
    console.log('entry ---', entry);
    entry.pipe(saxStream)
  })
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;使用本地的&amp;nbsp;XLSX&amp;nbsp;文件测试后，控制台打印出以下信息：&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/upyun/46a6eb77-7ae4-4896-bdd7-f3f6130ab585.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;这些信息对应着&amp;nbsp;XLSX&amp;nbsp;文档里的这部分信息。Node 里打印的 ST SI，代表着 xml 的标签。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/upyun/e6cde659-53d6-40c4-98e2-36e6ad976e7d.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;这样，其实我们也拿到了&amp;nbsp;XLSX&amp;nbsp;里的数据了，只不过这些数据还需要清洗、汇总、一一对应。同时由于我们是直接在可读流上操作，自然也可以 pause、resume 流，来实现分块读取和其他操作的逻辑。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;总结&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;对体积较小的&amp;nbsp;XLSX、CSV&amp;nbsp;文件，基本 SheetJS 就可以满足各种格式文件的解析需求了，但是一旦文档体积较大，那么分片、流式读写将成为必不可少的方式。&lt;/p&gt;

&lt;p&gt;通过前面例子和代码的分解，我们可以了解这类问题的解决办法，也可以拓展对类似需求的不同解决思路。一旦我们能对大体积文件的分块处理有一定的概念和了解，那么在遇到类似问题的时候，就知道实现思路在哪里了。&lt;/p&gt;</description>
      <author>upyun</author>
      <pubDate>Thu, 03 Mar 2022 15:58:46 +0800</pubDate>
      <link>https://ruby-china.org/topics/42179</link>
      <guid>https://ruby-china.org/topics/42179</guid>
    </item>
    <item>
      <title>对象存储服务（OSS）省钱建议</title>
      <description>&lt;p&gt;这篇文章简单谈谈对象存储服务的省钱建议，在创业公司干活，成本控制还是有点重要的，毕竟没有金主爸爸照顾，每个月省点钱，说不定就能“活”久一点。十分感谢 Ruby China 会员&lt;a href="https://ruby-china.org/jicheng1014" title=""&gt;哥有石头&lt;/a&gt;的指点。原文连接： &lt;a href="https://lanzhiheng.com/posts/save-money-in-oss" rel="nofollow" target="_blank"&gt;https://lanzhiheng.com/posts/save-money-in-oss&lt;/a&gt;&lt;/p&gt;

&lt;hr&gt;
&lt;h2 id="对象存储服务（OSS）"&gt;对象存储服务（OSS）&lt;/h2&gt;
&lt;p&gt;OSS 全称是 Object Store Service（对象存储服务）。这么说可能有点抽象。可以简单把它理解成一个托管资源的地方，这些资源也就是名称中的“对象”。运营网站的过程中总是少不了要存储，图片，小视频这些静态资源。如果是在服务器本机存储这些东西，维护成本太高，不利于迁移，并且容灾效果不佳。一般会建议“不要把鸡蛋放在同一个篮子里”，也就是托管到第三方的服务中去，而这个存储资源的服务名为对象存储服务。&lt;/p&gt;

&lt;p&gt;如果只有存储功能，那么 OSS 服务就更硬盘没啥区别了，它还必须要有外网访问的能力，这样你才能把东西上传上去（上行流量），并且把上传的东西供给别人访问/下载（下行流量）。简单来说 OSS 就是集存储与访问于一身的服务。还能够根据需要对自己的资源进行备份以免数据丢失。&lt;/p&gt;
&lt;h2 id="费用分析"&gt;费用分析&lt;/h2&gt;
&lt;p&gt;科技发展到今天这个地步，磁盘空间几乎已经成了最廉价的资源。故而在 OSS 中，存储费用其实是很低的。而在流量为王的年代，最贵的还得是流量。而对于任何服务来说基本都会是上行量要远小于下行量。故而下行流量也成了 OSS 中最为昂贵的一环。笔者公司上个月 OSS 服务的上行流量也就几十 G，而下行流量是 3.2TB 左右。下行流量换算成人民币大概是 1600 元，单价是 0.5 元/GB。当流量只有几百 G 的时候你可能感觉不到有啥，然而当流量上 T 之后，多少也会感到不安。按照网站如今的访问量，下个月的流量保守估计能到 5T。这笔费用想想就有点害怕。&lt;/p&gt;

&lt;p&gt;当时还是阿里云的双 11 活动，我们这边有两套方案&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;购买阿里云的 OSS 下行流量包，按年购买每个月 5TB 的流量，大概 1.6W 左右的费用，费用大概是 0.26 元/GB。&lt;/li&gt;
&lt;li&gt;不再使用 OSS 下行流量的方式直接读取资源。而是采用 CDN 回源的形式，下行流量统一走 CDN 流量，费用大概是 0.24 元/GB ~ 0.26 元/GB 这样。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;方案一比较省事，趁着双十一直接掏钱就完了，然而可扩展性极差，万一哪个月流量超 5TB，那么多出来的那部分依旧需要按照 0.5 元/GB 来计费，从长远来看并不是一个很好的选择，这么便宜的流量包也不是每个月都能买到。方案二则比较费事，需要配置 CDN 域名，CDN 访问 OSS 的权限，SSL 证书等等，不熟悉的话可能要折腾个大半天，然而长远来看不管每个月流量多少，都是按照 0.24 元/GB ~ 0.26 元来计算，果断选择方案二。&lt;/p&gt;

&lt;p&gt;所谓 CDN 回源，指的是当 CDN 服务并没能缓存到对应资源的时候需要回源到 OSS 端去下载。用户端访问 CDN 服务，CDN 服务找不到这个资源则再去 OSS 那边缓存资源到本地，所产生的费用跟用户端直接访问 OSS 获取资源是完全不同的。前者产生的叫回源流量，后者产生的是 OSS 下行流量。OSS 下行流量一般比较贵，量也比较大，回源流量一般量不会很大，CDN 有缓存之后都是直接从 CDN 返回，CDN 下行流量费用也相对便宜。&lt;/p&gt;

&lt;p&gt;虽说方案二除了 CDN 下行流量费用，还需要支付 HTTPS 费用（按照次数），以及回源流量费用，不过后面两者相对比较便宜，不管怎么算都比以“公共读”的方式从 OSS 直接获取资源要便宜许多。虽说方案二比较费事，但是费用降低了接近一半。假设每个月流量能达到 5TB 左右，粗略估计大概&lt;/p&gt;

&lt;p&gt;直接从 OSS 上读取：5 x 1024GB x 0.5 元/GB = 2560 元
CDN 回源优化之后：5 x 1024GB x 0.26 元/GB（CDN 下行流量是 0.24 元/GB，再加上回源流量，HTTPS 请求次数的费用，粗略按照 0.26 元/GB 计算）= 1331 元&lt;/p&gt;

&lt;p&gt;虽说不是很精确，但保守估计这个月能省个 1000 块钱左右吧，流量越大省的越多。&lt;/p&gt;
&lt;h2 id="更进一步"&gt;更进一步&lt;/h2&gt;
&lt;p&gt;上面是从云服务商本身做的优化，从 OSS 直连下载的模式切换到 CDN 回源到 OSS 的模式，原则上能省下一大笔。并且，还可以在此基础上做更多的优化工作&lt;/p&gt;
&lt;h2 id="购买流量包"&gt;购买流量包&lt;/h2&gt;
&lt;p&gt;一般来说购买流量包的流量费用要比按量付费要便宜。这里已经从 OSS 下行流量切换到 CDN 流量了，所以需要购买 CDN 下行流量包。OSS 的下行量流量包有点像中国移动的模式，购买流量包之后每个月都有定额流量，超额了要另外购买，用不完的就浪费掉了。而 CDN 的下行流量是，有效期是一年，用多少买多少，假设你买了 5T 的流量，用不完，下个月继续用，用完了再买就好，个人会更喜欢 CDN 这种模式。CDN 的下行流量包，笔者所购买的是 5T 的套餐，大概是 768 元，这样算下来单价是 0.15 元/GB。比起原来的 0.5 元/GB 的 OSS 下行费用，一个月下来要轻松不少呢。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://step-by-step.oss-cn-beijing.aliyuncs.com/production/63cw8k4niin797j6yas34laucpbw" title="" alt="套餐.png"&gt;&lt;/p&gt;
&lt;h2 id="节流"&gt;节流&lt;/h2&gt;
&lt;p&gt;后来发现公司自身的资源也有很大的优化空间，这方面不同的公司可能不一样。笔者的公司主要流量都是图片，视频。而其中的流量大头其实是视频。发现最开始用 iPhone 拍摄的视频大概是 20~30M 左右。这不仅上传耗时，用户下载视频也费流量。后来我们决定采用 720P 的配置来拍摄视频，视频大小大概缩小到 17M 左右，又因为用户是用手机预览的视频，所以几乎不会感觉到区别。&lt;/p&gt;

&lt;p&gt;在服务层面，再对原来 iPhone 拍摄出来的 MOV 格式的视频做压缩并转换成 MP4 格式，大小能够进一步减少，而且 MP4 格式的兼容性会相对好一些。转换后的视频大小大概是 2MB ~ 5MB 左右。以下是我的视频转换脚本，如果不执着于无损压缩，用这个配置去压缩的视频一般人肉眼也分辨不出来&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ffmpeg &lt;span class="nt"&gt;-i&lt;/span&gt; source.mov &lt;span class="nt"&gt;-vcodec&lt;/span&gt; h264 &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="nt"&gt;-preset&lt;/span&gt; veryfast target.mp4
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;视频成功转换并上传到云服务之后，转换后的视频依旧会保存在服务器，如果放着不管，一段时间之后磁盘必然会塞爆。这个时候做个定时任务处理一下即可&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# app/jobs/auto_clean_videos_directory_job.rb&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AutoCleanVideosDirectoryJob&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationJob&lt;/span&gt;
  &lt;span class="n"&gt;queue_as&lt;/span&gt; &lt;span class="ss"&gt;:default&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;perform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;_args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="no"&gt;FileUtils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rm&lt;/span&gt; &lt;span class="no"&gt;Dir&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;glob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'tmp/videos/*'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# config/schedule.yml&lt;/span&gt;

&lt;span class="ss"&gt;auto_clean_videos_directory_job:
  cron: &lt;/span&gt;&lt;span class="s2"&gt;"0 0 */10 * *"&lt;/span&gt;
  &lt;span class="ss"&gt;class: &lt;/span&gt;&lt;span class="s2"&gt;"AutoCleanVideosDirectoryJob"&lt;/span&gt;
  &lt;span class="ss"&gt;queue: :daily&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;倒也不用太频繁，每 10 天清除一遍遗留下来的视频数据就可以了。如果磁盘剩余空间小，可以考虑把频次提高一些。&lt;/p&gt;
&lt;h2 id="尾声"&gt;尾声&lt;/h2&gt;
&lt;p&gt;这篇文章简单总结了一下笔者近期在优化 OSS 费用方面所做的工作。目前看来比较经济的策略是 OSS 只做存储，下行流量走 CDN，再搭配上流量包，流量的费用能够节约不少。虽然说这种做法会产生回源流量，不过总的来说回源流量也要比 OSS 下行流量要便宜不少。而在自身服务层面，则可以尽可能降低资源的大小。咋一看从 15M 压缩到 5M 只少了 10M 似乎没什么，然而要是这个视频有 500 个人访问，那其实就相当于节省了 5G 左右的流量了。长远来看还是有点价值的。&lt;/p&gt;</description>
      <author>lanzhiheng</author>
      <pubDate>Thu, 16 Dec 2021 08:27:27 +0800</pubDate>
      <link>https://ruby-china.org/topics/41989</link>
      <guid>https://ruby-china.org/topics/41989</guid>
    </item>
    <item>
      <title>热门剧本杀与 SaaS 的不解之缘</title>
      <description>&lt;p&gt;近年来，“剧本杀”这种以剧本为核心，玩家分别扮演不同角色推理案情找出真凶的娱乐项目在年轻人的范围内迅速传开，已悄然形成了一个市场规模超百亿的新兴产业，吸引了大量淘金者。而在互联网时代，针对玩家线上剧本杀的需求和店家维护用户的要求，叫做“剧本杀 SaaS”的小程序也应运而生。在小程序里，可以为剧本杀店家提供剧本目录、组局、会员管理、员工管理等多种功能。每个月仅花费几百元的云开发费用，便可开发和维护数千个微信小程序。正如名称所显示的那样，程序所运用的是 SaaS 云技术，这种技术简介易用为创业者，也为消费者提供了更多选择和便利。当然，我们今天要聊的重点并不是剧本杀，而是要来聊聊 SaaS。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/upyun/bace11ca-e8f6-4348-bdf7-a48efd50a4d7.png!large" title="" alt="“百变大侦探”热门剧本"&gt;&lt;/p&gt;
&lt;h2 id="什么是 SaaS"&gt;什么是 SaaS&lt;/h2&gt;
&lt;p&gt;SaaS（软件即服务）是目前最流行的云计算形式之一。它与 IaaS（基础设施即服务）和 PaaS（平台即服务）并驾齐驱。SaaS 是一种基于云的软件交付模型。在该模型中，云服务商开发、提供并维护云应用软件，保持软件的自动更新，同时通过互联网，以按需付费的方式向其客户提供服务。公有云提供商管理所有硬件和传统软件，包括中间件、应用软件及其安全性。因此 SaaS 客户可以显著降低成本，便于维护本地系统和软件更快地部署、扩展，升级业务解决方案，并更准确地预测所需成本及费用。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/upyun/8fc59b12-658b-4f0c-a701-6cb56b0c9b38.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;SaaS 的历史可以追溯到 60 年代，当时出现了一种称为分时的软件交付系统，将大型计算机连接到共享大型机软件的哑终端（只有输入输出字符的功能，没有处理器或硬盘称为“哑终端”）。随着 90 年代互联网的出现，提供商开始托管软件并通过互联网将其提供给客户。然而，这种 SaaS 的先驱，称为应用程序服务提供商 (ASP) 模型，具有严重的局限性。例如，每个客户都需要自己的软件版本，这意味着必须在用户的计算机上安装一些软件，配置既昂贵又耗时。&lt;/p&gt;

&lt;p&gt;第一个 SaaS 解决方案出现在 90 年代后期，当时 SaaS 一词最初被创造出来。这种新模型提供了比 ASP 模型更高的效率。由于其所谓的多租户架构，应用程序的单个实例可以为多个用户甚至客户提供服务，不再需要本地安装软件。它提供了一种收集、聚合和集中有价值的应用程序数据的方法。自 2000 年以来，SaaS 已从第一代孤立的解决方案显着演变为现代的 SaaS 套件，这些套件可在整个业务中实现高度可见性，并广泛用于人工智能、机器学习、物联网、区块链、增强现实和虚拟现实等多项技术。&lt;/p&gt;
&lt;h2 id="SaaS 模型的优势和风险"&gt;SaaS 模型的优势和风险&lt;/h2&gt;
&lt;p&gt;SaaS 的最大优势是它将所有基础设施和应用程序管理委托给了 SaaS 供应商。用户所要做的就是创建一个帐户，支付费用并开始使用该应用程序。供应商负责处理其他所有事情，从维护服务器硬件和软件到管理用户访问和安全、存储和管理数据、实施升级和补丁等等。其他优势还包括：&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;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;易于扩展：提供高度的垂直可扩展性，让客户可以选择按需访问更多或更少的服务或功能。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;可访问性和持久性：由于 SaaS 供应商通过 Internet 交付应用程序，因此用户可以从任何支持 Internet 的设备和位置访问它。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;在使用便利的同时，SaaS 也带来了一些潜在的风险和挑战，因为企业必须依赖外部供应商提供软件，保持软件正常运行，跟踪和报告准确的计费，依赖供应商为企业数据提供安全的环境。因此就导致了一些隐患：&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;当提供商遇到服务中断、对服务产品进行不必要的更改或遇到安全漏洞时，这些都会对客户使用的 SaaS 产品产生深远的影响。为了解决这些问题，客户应了解其 SaaS 提供商的 SLA 并确保其执行到位。另外，客户失去了对服务版本的控制，如果提供商更新了新版本的应用程序，那么它会向所有客户推送，无论客户是否真的需要更新版本。最复杂的要属更换供应商，客户必须迁移非常大量的数据。此外，一些供应商使用专有技术和数据类型，这会使不同云提供商之间的客户数据传输更加繁琐。&lt;/p&gt;

&lt;p&gt;除了上述问题，云安全也被认为是 SaaS 应用程序最重大的挑战之一。&lt;/p&gt;
&lt;h2 id="SaaS vs PaaS vs IaaS"&gt;SaaS vs PaaS vs IaaS&lt;/h2&gt;
&lt;p&gt;既然说了 SaaS，当然也不得不提一下它的其他俩兄弟 —— IaaS 和 PaaS。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/upyun/9532a0cb-49f3-477d-988b-550ab00833c0.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;IaaS 即基础设施即服务，是对云计算基础设施（服务器、存储和网络资源）的按需访问，客户可以像使用本地硬件一样配置和使用这些基础设施。不同之处在于云服务提供商在自己的数据中心托管、管理和维护硬件及计算资源。IaaS 客户通过互联网连接使用硬件，并以订阅或按需的方式支付使用费用。&lt;/p&gt;

&lt;p&gt;PaaS 即平台即服务，它为开发、运行和管理应用程序提供了一个基于云的平台。云服务提供商托管、管理和维护平台中包含的所有硬件和软件，包括服务器（用于开发、测试和部署）、操作系统 (OS) 软件、存储、网络、数据库、中间件、框架、开发工具，以及安全、操作系统和软件升级、备份等相关服务。用户通过图形用户界面（GUI）访问 PaaS，开发或 DevOps 团队可以在其中协作处理整个应用程序生命周期中的所有工作，包括编码、集成、测试、交付、部署和反馈。&lt;/p&gt;

&lt;p&gt;SaaS、PaaS、IaaS 并不相互排斥，而是共同构成了云计算最基础的服务层——公有云。三个模型对产品的完整性进行了不同方面的补充。其中 SaaS 产品是完整且完全托管的应用程序。IaaS 主要是外包数据中心资源，PaaS 提供由提供商的数据中心托管的开发平台和其他工具。&lt;/p&gt;

&lt;p&gt;同时这三种“即服务”都有着成本低，不需要假设任何设备、配置管理人员就可以让客户享受专用 IT 服务的特色，这方便了客户按照自己的需求选择不同的方案，灵活便捷。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/upyun/bad94fa6-b7c7-41e3-ba44-d8cc00278e73.png!large" title="" alt="传统 IT、IaaS、PaaS 和 SaaS 的管理职责分布"&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/upyun/175b8e97-bd58-4fbe-88d9-a5858b0a32ef.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;正如文章开头提及的“剧本杀 SaaS”以小程序的形式存在，简单接入就可以使用一样。SaaS 解决方案不需要用户承担各种不必要的技术担忧以及设计、网络等不确定的因素影响，可以简单快速推动各个行业接入云服务，加快行业创新和增长，无疑是最受欢迎的服务模式啦~&lt;/p&gt;
&lt;h4 id="推荐阅读"&gt;推荐阅读&lt;/h4&gt;
&lt;p&gt;&lt;a href="https://www.upyun.com/tech/article/672/TypeScript%20%E6%9E%9A%E4%B8%BE%E6%8C%87%E5%8D%97.html" rel="nofollow" target="_blank" title=""&gt;TypeScript 枚举指南&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.upyun.com/tech/article/673/%E5%AE%9E%E6%88%98%E7%BB%8F%E9%AA%8C%E5%88%86%E4%BA%AB%EF%BC%9A%E4%BD%BF%E7%94%A8%20PyO3%20%E6%9D%A5%E6%9E%84%E5%BB%BA%E4%BD%A0%E7%9A%84%20Python%20%E6%A8%A1%E5%9D%97.html" rel="nofollow" target="_blank" title=""&gt;实战经验分享：使用 PyO3 来构建你的 Python 模块&lt;/a&gt;&lt;/p&gt;</description>
      <author>upyun</author>
      <pubDate>Tue, 09 Nov 2021 14:48:05 +0800</pubDate>
      <link>https://ruby-china.org/topics/41864</link>
      <guid>https://ruby-china.org/topics/41864</guid>
    </item>
    <item>
      <title>腾讯云涉嫌不正当竞争，Ruby China 也中标</title>
      <description>&lt;p&gt;如果网站不是用的腾讯云服务器，那么在 QQ、腾讯浏览器、腾讯邮箱等腾讯旗下产品打开的时候，很大可能会出现这种提示&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/gaicitadie/073a1a22-8bb2-4b7a-bcb3-5e5dda985779.png!large" title="" alt=""&gt;&lt;br&gt;
还有可能被提示：“该站点被用户投诉含有非法诈骗内容！”，至于是不是真有用户投诉，只有腾讯知道，总之这种页面可以吓退一大半访客。&lt;/p&gt;

&lt;p&gt;注意下面有个“申请恢复访问”，点开是这个链接：&lt;a href="https://urlsec.qq.com/complain.html?url=https%3A%2F%2Fruby-china.org%2Ftopics" rel="nofollow" target="_blank"&gt;https://urlsec.qq.com/complain.html?url=https%3A%2F%2Fruby-china.org%2Ftopics&lt;/a&gt;&lt;br&gt;
页面如图：&lt;br&gt;
&lt;img src="https://l.ruby-china.com/photo/gaicitadie/a7b9e342-c157-42cb-9b58-fcac84898c91.png!large" title="" alt=""&gt;&lt;br&gt;
像 ruby china 这种不使用腾讯云的网站，只能走下面的“普通申诉”，普通申诉受理的时间为 1-3 天不等，也就是说，就算你的网站是被冤枉的，申诉以后也可能需要等 3 天才有结果。&lt;br&gt;
我的网站几乎每隔 10 天就“被用户投诉一次”，然后中标，然后我发现以后进行普通申诉，然后等个 1-3 天解封，如此反复，已经有 4、5 次了，虽然每次腾讯都表示是误封，是用户的恶意投诉，然而我的损失是实实在在的，因为腾讯的审查的延误给我造成的损失由谁来赔偿？&lt;/p&gt;

&lt;p&gt;然后我们再来看看上面所谓的“安心计划”，打开是这个页面：&lt;a href="https://lrsm.urlsec.qq.com/lrsm#/anxin" rel="nofollow" target="_blank"&gt;https://lrsm.urlsec.qq.com/lrsm#/anxin&lt;/a&gt; &lt;br&gt;
购买“安心计划”就不用吃上面的那些苦头，首先要把网站转到腾讯云，然后买越贵的套餐，解封速度越快。&lt;/p&gt;

&lt;p&gt;而不加入“安心计划”的网站，拦截以后连通知都没有，也不告诉你到底是哪里出现了敏感内容。这不就是赤裸裸的敲诈勒索吗？马化腾果然会闷声发大财。&lt;/p&gt;

&lt;p&gt;我的网站已经被连续敲诈几个月了，虽然每次都以解封收场，但是每次都要把我的网站误封好几天。我已经在搜集证据，向媒体曝光腾讯的恶行，向工信部投诉腾讯不正当竞争。&lt;/p&gt;</description>
      <author>gaicitadie</author>
      <pubDate>Thu, 21 Oct 2021 21:39:37 +0800</pubDate>
      <link>https://ruby-china.org/topics/41787</link>
      <guid>https://ruby-china.org/topics/41787</guid>
    </item>
    <item>
      <title>[又拍云] 上云特惠，云主机、SSL 证书全场 6 折，短信包 1000 条 30 元，更多优惠等你来</title>
      <description>&lt;p&gt;上云特惠，全场 5 折起。&lt;/p&gt;

&lt;p&gt;从基础到扩展，助企业打造全面云生态。&lt;/p&gt;

&lt;p&gt;从云主机、CDN、云存储活动，到 短信、SSL 证书、DDoS 高防等活动，应有尽有。&lt;/p&gt;

&lt;p&gt;云主机、SSL 证书全场 6 折，短信包 1000 条 30 元，一键登录惊爆价只要 0.025 元 /次……更多优惠等你来看。&lt;/p&gt;

&lt;p&gt;活动传送门： &lt;a href="https://www.upyun.com/yunSpecial" rel="nofollow" target="_blank"&gt;https://www.upyun.com/yunSpecial&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/upyun/a79000a7-8e0f-4c84-a256-1fb31e19a57e.jpeg!large" title="" alt=""&gt;&lt;/p&gt;</description>
      <author>upyun</author>
      <pubDate>Mon, 24 May 2021 14:20:27 +0800</pubDate>
      <link>https://ruby-china.org/topics/41297</link>
      <guid>https://ruby-china.org/topics/41297</guid>
    </item>
    <item>
      <title>备考 AWS Certified Solution Architect Associate(英文) 经验</title>
      <description>&lt;p&gt;我以前在一家大公司工作的时候，基础设施全部在一个简陋的私有云上。简陋到什么程度呢？差不多脏活累活都是手工处理，而不是自动化。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;负载均衡是 F5 load balancer -&amp;gt; HAProxy -&amp;gt; Nginx&lt;/li&gt;
&lt;li&gt;数据库的备份都是专人负责。&lt;/li&gt;
&lt;li&gt;文件存储都是 mount volume，满了要扩容。&lt;/li&gt;
&lt;li&gt;要先发邮件向安全部门申请 HTTPs 证书，安全部门再向 Symantec 申请新证书，然后配置到负载均衡上。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;后来团队招了一个 AWS Solution Architect，他天天在办公室大谈公有云的好处。RDS 的服务多么稳定，升级如何贴心，S3 存储无限空间。换句话说，我们的私有云真烂。&lt;/p&gt;

&lt;p&gt;文人相轻，程序员也一样。我心里常常嘀咕，你懂 Memeched 基于客户端的分布式吗？你懂一致性 hash 吗？你懂数据库的 Binlog 吗？你懂 Certificate Chain 吗？你懂 HTTP/2 吗？&lt;/p&gt;

&lt;p&gt;你丫的就是个 AWS 配置工程师，就知道随便点点按钮，内部原理压根不懂。&lt;/p&gt;
&lt;h2 id="为什么备考 AWS？"&gt;为什么备考 AWS？&lt;/h2&gt;
&lt;p&gt;后来我离开了大公司，跳出了私有云的大火坑。新的职场使用 AWS 全家桶，我开始了解 AWS。不用不知道，一用真是好，AWS 做的云产品甩出大公司私有云十条街。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;数据库可以开启 Multi-AZ，数据中心故障时，可以自动切换到另外一个 Availability Zone&lt;/li&gt;
&lt;li&gt;文件可以往 S3 里随便扔，容量无限制，再也不用 mount volume&lt;/li&gt;
&lt;li&gt;HTTPs 的证书可以自动更新，不需要手工操作。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;新世界的大门向我开启，原来运维的工作可以这么简单。我为当初的傲慢无理非常羞愧 (虽然他不知道)，向那位 AWS Solution Architect 道歉。&lt;/p&gt;

&lt;p&gt;我也冒出了考 AWS Solution Architect 的想法。&lt;/p&gt;

&lt;p&gt;一，符合我的职业规划。国内的工作机会 996 严重，工作的自由度低。为了平衡家庭和工作，我大概率会在外企这条路继续走下去。2020 年 AWS 全球市场份额占 31%，Azure 占 20%。AWS 知识可以在未来的职场不断被使用。&lt;/p&gt;

&lt;p&gt;二，我目前所在的公司 workstream.us 重度使用 AWS 的各种产品，备考 AWS Certified Solution Architect 可以帮助我改进公司的现有的架构。备考试题中有大量的模拟场景，我可以学到应对各种场景的最佳实践。&lt;/p&gt;

&lt;p&gt;三，AWS Certified Solution Architect – Associate 含金量很高，长期处于&lt;a href="https://www.globalknowledge.com/us-en/resources/resource-library/articles/top-paying-certifications/#gref" rel="nofollow" target="_blank" title=""&gt;最受欢迎的认证排行榜前 2 位&lt;/a&gt;。有人统计过，持有该证书的工程师平均年薪是 11-14 万美金。如果你在外企工作，看在钱的份上，你也应该考此证书。&lt;/p&gt;
&lt;h2 id="什么时候开始备考比较合适？"&gt;什么时候开始备考比较合适？&lt;/h2&gt;
&lt;p&gt;AWS 的产品线非常的广，如果你们公司技术栈没有真实的使用过一些产品，死记硬背效果很差。AWS 推荐程序员使用 1 年 AWS 的产品之后再备考，效果更好。&lt;/p&gt;

&lt;p&gt;学以致用。如果你们公司用到的技术栈是阿里云，不如考阿里云认证。如果你们公司用到了 Azure，不如考 Azure 的认证。这样更加事半功倍。&lt;/p&gt;
&lt;h2 id="备考材料有哪些？"&gt;备考材料有哪些？&lt;/h2&gt;
&lt;p&gt;我的英文水平：读文档流畅，听力也还凑合，但是说话不流畅。&lt;/p&gt;

&lt;p&gt;一开始我直接购买了 AWS 官方推荐的教材《AWS Certified Solutions Architect Official Study Guide: Associate Exam (Aws Certified Solutions Architect Official: Associate Exam)》&lt;a href="https://www.amazon.com/Certified-Solutions-Architect-Official-Study/dp/1119138558" rel="nofollow" target="_blank" title=""&gt;(链接)&lt;/a&gt;，通过学习教材备考。&lt;/p&gt;

&lt;p&gt;通读全书之后很快发现了几个问题：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;不清楚考试的重点章节。&lt;/li&gt;
&lt;li&gt;不熟悉考试题型。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;后来翻看了国外网友的一些考试经验，发现很多人都会买在线课程，通过课程学习 AWS 知识，然后手把手的去操作一遍加深印象。然后刷几套模拟题，评估自己的真实水平。&lt;/p&gt;

&lt;p&gt;于是我在 Udemy 上购买了销量最好的一套课程和一套模拟题：&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.视频教学课程，作者  Stéphane Maarek&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;《Ultimate AWS Certified Solutions Architect Associate》&lt;a href="https://www.udemy.com/share/102CPBAEMadldSRn8J/" rel="nofollow" target="_blank" title=""&gt;(链接)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. 模拟题，作者 Tutorials Dojo&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;《AWS Certified Solutions Architect Associate Practice Exams》&lt;a href="https://www.udemy.com/course/aws-certified-solutions-architect-associate-amazon-practice-exams-saa-c02/" rel="nofollow" target="_blank" title=""&gt;(链接)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;tips: 我刷模拟题得分 92-96 分，去考场真实考试只有 78 分。如果你模拟题分数很高，不要对自己过分自信。&lt;/p&gt;
&lt;h2 id="学习时遇到的一些困难"&gt;学习时遇到的一些困难&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;学习内容中包含了大量的“用不上的知识”，只能死记硬背。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;我所在的公司是直接用的云产品，不存在数据迁移的问题。但是 AWS 考试题会有大量 on premise 数据迁移相关的内容，考察开发者帮助传统的企业上云面临的各种挑战。&lt;/p&gt;

&lt;p&gt;把传统的数据中心的文件迁移到云上的业务，要用到 DataSync 去把本地数据中心的数据同步到 S3.&lt;/p&gt;

&lt;p&gt;把机房的数据库同步到 AWS RDS，要用到 AWS Database Migration Service。&lt;/p&gt;

&lt;p&gt;所以只能死记硬背这些知识。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;不得不在 AWS 一些非主流产品上上投入时间&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AWS 的大部分云产品是非常优秀的，但是还是会有很多非主流产品。&lt;/p&gt;

&lt;p&gt;比如 CodeCommit 是 AWS 开发的简单 git server，可以帮助开发者托管代码。现如今大家都会用 Github/Gitlab, 谁会用 CodeCommit 呢？&lt;/p&gt;
&lt;h2 id="备考时间"&gt;备考时间&lt;/h2&gt;
&lt;p&gt;我知道一些很聪明的程序员只备考了 2 个月就考试通过了。我很慢，花了一年半的时间学习备考。&lt;/p&gt;

&lt;p&gt;首先是因为工作忙碌，每天只能用碎片时间学习一个知识点。&lt;/p&gt;

&lt;p&gt;其次，AWS 的考试题让我看到自身薄弱的计算机基础知识，我经常会花 1-2 周去搞明白。说来惭愧，我工作 8 年了，一直没有搞明白 IP / Network Mask / CIDR。我花了 2 周时间彻底搞明白了。&lt;/p&gt;

&lt;p&gt;最后，学习本身很快乐，考试通过是副产品。所以备考也不慌不忙。&lt;/p&gt;

&lt;p&gt;这是我 2020 年每周在 AWS 方面的&lt;a href="https://mednoter.com/plan-for-2020.html#3%E8%80%83%E4%B8%AA-aws-certified-solutions-architect-%E8%AF%81%E4%B9%A6" rel="nofollow" target="_blank" title=""&gt;学习的记录&lt;/a&gt;，别人是日拱一卒，我是”周“拱一卒。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://mednoter.com/media/files/2021/2021-04-27-log.jpg" title="" alt=""&gt;&lt;/p&gt;
&lt;h2 id="如何预约考试？"&gt;如何预约考试？&lt;/h2&gt;
&lt;p&gt;当你在 Udemy 上模拟题可以刷到 92 分左右的时候，就可以报名考试了。&lt;/p&gt;

&lt;p&gt;预约网站： &lt;a href="https://www.aws.training/" rel="nofollow" target="_blank" title=""&gt;aws.training&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;考试费用：150 美金。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://mednoter.com/media/files/2021/2021-04-27-schedule-exam.jpg" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;AWS 的考试安排会有两个渠道“通过 PSI 安排”和“通过  Pearson Vue”安排。我一开始不太懂他们是什么，区别是什么。&lt;/p&gt;

&lt;p&gt;他们是两个考试机构，你可以理解他们是专门监考的公司，AWS 和他们合作，你去 PSI 或 Pearson 公司去考试，他们会负责核对身份，监考。大千世界，无奇不有，有公司靠监考赚钱。&lt;/p&gt;

&lt;p&gt;两家考试机构，并无太大区别，你选择一家离你近的考点就可以。&lt;/p&gt;

&lt;p&gt;这是 PSI 上海人民广场的一个考点，监考员首先会用身份证和其他证件核实身份，考场就是一个 6 人会议室大小的房间，里面有电脑。到了考试时间，监考员会给你打开电脑，你用指定的电脑开始考试。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://mednoter.com/media/files/2021/2021-04-27-psi.jpg" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;预约中文版还是英文版？&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AWS 考试题有中文版和英文版供选择。&lt;/p&gt;

&lt;p&gt;如果预约中文版，考试时每个题目既可以选择中文，也可以选择英文。我的朋友预约的是中文版，他考一个半小时就交卷了。&lt;/p&gt;

&lt;p&gt;我预约的是英文版，考试时发现和模拟题的表述差距很大，有些题目描述的非常晦涩。我每道题目要读好几遍，足足考了 130 分钟。&lt;/p&gt;
&lt;h2 id="考试过程中遇到的一些困难"&gt;考试过程中遇到的一些困难&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;一些题目会模拟出一个场景，然后让你选择合适的解决方案。但它提供的正确解决方案并不是完美答案。我只能用排除法排除掉明显的错误选项，勉为其难的选一个将就的答案。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;一个电商网站 example.com 有静态内容，也有动态内容，它面临着越来越多的流量，以下选项那些可以改进性能  &lt;/p&gt;

&lt;p&gt;A: enable CloudFront (正确答案)    &lt;/p&gt;

&lt;p&gt;B: Use S3 static website  &lt;/p&gt;

&lt;p&gt;C: ...  &lt;/p&gt;

&lt;p&gt;D: ...  &lt;/p&gt;

&lt;p&gt;在真实的场景里大家肯定会把静态资源剥离到单独的域名 &lt;code&gt;files.example.com&lt;/code&gt; 或 &lt;code&gt;img.example.com&lt;/code&gt; ，用 CDN 响应；动态内容则用主站渲染。&lt;/p&gt;

&lt;p&gt;很少有人会直接给主站开启 CloudFront，然后根据不同的 url 设置不同的 CDN behavior。但是鉴于其他选项明显错误，我只能勉为其难的选 A。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;有些题目则完全是抠字眼。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;比如某些题目啰哩啰嗦的描述了一个场景，这个场景最适合的解决方案并不是 DynamoDB。但是题目中出现了一个关键字 &lt;code&gt;microseconds&lt;/code&gt;, 这时候我只能闭着眼睛选 &lt;code&gt;DynamoDB + DAX&lt;/code&gt; 。AWS 要昭告全世界，microseconds 太快了，快死了。如果我不选这个选项，我就要丢分了。&lt;/p&gt;

&lt;p&gt;真希望出题的人质量高一点，能把真实世界的架构带到考试题中，让考试的人和出题的人的脑电波在一个频率上。&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;AWS Certified Solution Architect Associate Exam 考察的知识点非常的全面。&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;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;祝你考试顺利。&lt;/p&gt;</description>
      <author>xiaoronglv</author>
      <pubDate>Tue, 27 Apr 2021 13:43:49 +0800</pubDate>
      <link>https://ruby-china.org/topics/41195</link>
      <guid>https://ruby-china.org/topics/41195</guid>
    </item>
    <item>
      <title>CHDFS 安全便捷的大数据访问体验</title>
      <description>&lt;p&gt;一、背景&lt;/p&gt;

&lt;p&gt;云 HDFS（Cloud HDFS，CHDFS）是腾讯云提供的支持标准 HDFS 访问协议、卓越性能、分层命名空间的分布式文件系统。&lt;/p&gt;

&lt;p&gt;CHDFS 主要解决大数据场景下海量数据存储和数据分析，能够为大数据用户在无需更改现有代码的基础上，将本地自建的 HDFS 文件系统无缝迁移至具备高可用性、高扩展性、低成本、可靠和安全的 CHDFS 上。以此实现存算分离，实现计算节点可动态的扩缩容。&lt;/p&gt;

&lt;p&gt;因此 CHDFS 主要的用户群体是大数据体系的研发人员，为了满足用户在传统的 Hadoop 环境下的使用习惯，同时满足用户的权限需求，CHDFS 通过以下措施，提供了安全便捷的大数据访问体验。&lt;/p&gt;

&lt;p&gt;二、来源管控&lt;/p&gt;

&lt;p&gt;存算分离带来了存储的云端托管，使计算节点不再依赖本地的存储，但同时也带来了存储时延的增加，因此存算分离更适合于同地域同机房的访问。CHDFS 在设计之初，就假定用户的大数据集群运行在腾讯云的 VPC 网络 (包括 CVM 和黑石)。&lt;/p&gt;

&lt;p&gt;因此用户只用通过以下三步，即可限制来源：&lt;/p&gt;

&lt;p&gt;1、新建权限组，并在权限组中指定 VPC(必须本账户下的 VPC)。
&lt;img src="https://l.ruby-china.com/photo/Cloud_Storage_Angel/ee622ede-5392-4da6-8546-5cd8a3ca2d58.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;2、在权限组里面添加规则，授予 VPC 网段里的某一个子网段的只读或者读写权限。同一个权限组中的多条规则，根据优先级来确定权限。
&lt;img src="https://l.ruby-china.com/photo/Cloud_Storage_Angel/733d65ed-873a-426b-9a28-be9ae27aa5b0.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;3、在文件系统的挂载点中绑定权限组，一个文件系统可以绑定多个权限组，请求满足任何一个权限组的规则，即获得相应的访问权限。
&lt;img src="https://l.ruby-china.com/photo/Cloud_Storage_Angel/0672a3bd-f842-40c5-9851-bf49d073acce.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;三、POSIX 权限与超级用户&lt;/p&gt;

&lt;p&gt;CHDFS 兼容 HDFS 的 POSIX 的权限规则，该权限规则和 Linux 文件系统的的规则类似。即每一层的目录和文件都有 User，Group 与 Other 权限 (rwx)。整个权限规则可简述如下：&lt;/p&gt;

&lt;p&gt;1、用户执行 Hadoop 命令行或者运行某个大数据 JOB&lt;/p&gt;

&lt;p&gt;2、Job 运行中需要访问 CHDFS 的某个路径，即以执行进程的用户身份与组身份访问 CHDFS 的某个路径。&lt;/p&gt;

&lt;p&gt;3、CHDFS 从根据访问的路径，从根目录开始，层层检查。如果用户名匹配文件或者目录的用户名，则拥有文件和目录的 User 权限，如果用户组名匹配，则拥有 Group 权限，否则只拥有 Other 权限。&lt;/p&gt;

&lt;p&gt;4、对于目录要进入下一层，必须拥有 X 权限，对于目录下创建删除文件必须拥有 W 权限，对于列出目录下的文件，必须有 R 权限。&lt;/p&gt;

&lt;p&gt;5、对于读取文件，必须要有 R 权限，对于修改文件必须有 W 权限。&lt;/p&gt;

&lt;p&gt;对于普通用户，使用以上的权限规则进行校验，但同时 CHDFS 也支持了超级用户，超级用户拥有对文件目录的一切操作权限，适用于配置管理员。&lt;/p&gt;

&lt;p&gt;POSIX 的权限开关与超级用户的设置，可以在新建文件系统时，或者在后续在文件系统属性下编辑。
&lt;img src="https://l.ruby-china.com/photo/Cloud_Storage_Angel/6411a021-9b14-4867-9d5f-3f319d6016be.png!large" title="" alt=""&gt;
&lt;img src="https://l.ruby-china.com/photo/Cloud_Storage_Angel/33b771d2-a2ae-438f-9629-7ce38049a253.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;四、接入 Hadoop Ranger 权限体系&lt;/p&gt;

&lt;p&gt;Hadoop Ranger 作为一站式的权限体系解决方案，不仅支持存储端权限管控，还支持 YARN，Hive 等组件权限管控。因此，为了维持客户的使用习惯，我们提供了 CHDFS 的 Ranger 接入解决方案，方便客户使用 Ranger 来进行 CHDFS 的权限管控。CHDFS 接入 Ranger 权限体系的架构如下所示
&lt;img src="https://l.ruby-china.com/photo/Cloud_Storage_Angel/15a9d6e7-6f83-4435-835f-c2e709482ff6.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;我们在 Ranger Admin 控制中心，注册 CHDFS 服务的相关信息，并配置 CHDFS 的服务后，即可配置 CHDFS 的相关权限 policy，如下所示。
&lt;img src="https://l.ruby-china.com/photo/Cloud_Storage_Angel/6df6ac36-484f-462b-9f6a-56809c1bc5d7.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;CHDFS 插件端开启进行 ranger 鉴权后，即会把所有访问 CHDFS 的请求转发给 COS Ranger Service 进行鉴权，COS Ranger Service 根据从 Ranger Admin 拉取 policy，进行权限检查。有关 CHDFS 接入 Ranger 权限的配置说明，请参考 CHDFS 控制台文档（&lt;a href="https://cloud.tencent.com/document/product/1105/53307" rel="nofollow" target="_blank"&gt;https://cloud.tencent.com/document/product/1105/53307&lt;/a&gt;）。&lt;/p&gt;

&lt;p&gt;五、总结&lt;/p&gt;

&lt;p&gt;CHDFS 作为云端托管的大数据存储，从设计之初，就充分考虑了 HDFS 用户的使用习惯。通过提供限制来源 VPC、IP 网段、POSIX 鉴权、超级用户等特性，并支持接入 Hadoop Ranger 权限体系。方便客户的同时，也充分的保证了安全性与灵活性。&lt;/p&gt;

&lt;p&gt;关于我们&lt;/p&gt;

&lt;p&gt;云 + 社区「腾讯云存储团队」主页（&lt;a href="https://cloud.tencent.com/developer/team/storage" rel="nofollow" target="_blank"&gt;https://cloud.tencent.com/developer/team/storage&lt;/a&gt;），涵盖了腾讯云存储团队最新动态、团队信息、产品矩阵、技术文档、视频教程等，欢迎关注或留言，给出您的宝贵建议。&lt;/p&gt;</description>
      <author>Cloud_Storage_Angel</author>
      <pubDate>Fri, 05 Mar 2021 16:16:58 +0800</pubDate>
      <link>https://ruby-china.org/topics/40998</link>
      <guid>https://ruby-china.org/topics/40998</guid>
    </item>
    <item>
      <title>云端大数据分布式文件系统 成本优化秘笈</title>
      <description>&lt;p&gt;一、CHDFS 介绍&lt;/p&gt;

&lt;p&gt;CHDFS（云 HDFS）是腾讯云一种提供标准 HDFS 访问协议和分层命名空间的高性能分布式文件系统，主要解决大数据场景下海量数据存储和数据分析，为实现计算与存储分离提供解决方案。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/Cloud_Storage_Angel/5e5ba21e-7fb8-4cd3-b234-14d46572d891.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;CHDFS 着重于分布式元数据服务，数据存储依赖对象存储 COS。COS 作为云端基础存储服务，为 CHDFS 提供了坚实的数据底座，不仅支持海量数据存储和超大带宽，还支持多 AZ 模式，且默认 EC 编码，成本更低，同时通过冷热数据智能分层，进一步降低存储成本。&lt;/p&gt;

&lt;p&gt;二、生命周期管理&lt;/p&gt;

&lt;p&gt;随着时间推移，CHDFS 上数据不断累积，但只有小部分是用户最近使用的，大部分是历史数据，访问频次逐渐减少，如日志文件，数据备份等。&lt;/p&gt;

&lt;p&gt;如果用户不去管理这些数据，那么存储费用逐渐增大，对用户自身业务发展也不友好，但主动管理需要投入人力和时间成本，费时费力，因此 CHDFS 对齐 COS 数据分层能力，推出生命周期功能，帮助用户更加便捷地管理冷热数据。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/Cloud_Storage_Angel/618c2e6e-e86f-4ce7-bebf-2ad4fac3de3d.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;用户可以通过配置 CHDFS 生命周期规则，定期将数据文件从标准存储降为归档存储或者直接删除，整个沉降和删除过程由 CHDFS 生命周期功能自动化完成，保障及时准确，且不产生任何附加费用，同时支持回热操作，用于对已经降为归档存储类型的数据文件重新发起访问。&lt;/p&gt;

&lt;p&gt;三、生命周期规则&lt;/p&gt;

&lt;p&gt;生命周期规则即生命周期策略，需要用户指定以下参数：&lt;/p&gt;

&lt;p&gt;1、Path：生命周期规则目标路径。&lt;/p&gt;

&lt;p&gt;1）指定目录：规则作用于目录下的所有文件，包括递归子目录下的文件。&lt;/p&gt;

&lt;p&gt;2）指定文件：规则只作用于具体文件。&lt;/p&gt;

&lt;p&gt;2、Type：生命周期规则类型。&lt;/p&gt;

&lt;p&gt;1）沉降：定期将文件存储类型从标准存储降为归档存储，节省成本。&lt;/p&gt;

&lt;p&gt;2）删除：定期将文件直接删除。&lt;/p&gt;

&lt;p&gt;3、Days：指定生命周期规则在文件最后访问时间的多少天后触发相应的操作。&lt;/p&gt;

&lt;p&gt;说明：与 COS 对象最后修改时间 mtime 不同，CHDFS 满足文件系统语义，不仅支持文件最后修改时间 mtime、元数据最后修改时间 ctime，还能够支持以文件最后访问时间 atime 作为分层条件，这种策略更能满足用户需求。&lt;/p&gt;

&lt;p&gt;四、回热任务&lt;/p&gt;

&lt;p&gt;回热的目的是为了对已经沉降的文件重新发起访问，它会复制一份标准存储的文件副本供用户读取，副本到期后会自动删除，在此期间归档存储的文件一直存在，创建回热任务需要用户指定参数：&lt;/p&gt;

&lt;p&gt;1、FilePath：回热文件路径。&lt;/p&gt;

&lt;p&gt;2、Type：回热类型。根据回热时间长短，回热分为三类。&lt;/p&gt;

&lt;p&gt;1）极速模式：回热任务在 1 - 5 分钟内可完成。&lt;/p&gt;

&lt;p&gt;2）标准模式：回热任务在 3 - 5 小时内完成。&lt;/p&gt;

&lt;p&gt;3）批量模式：回热任务在 5 - 12 小时内完成。&lt;/p&gt;

&lt;p&gt;3、Days：回热完成后，标准存储的文件副本的保留天数。&lt;/p&gt;

&lt;p&gt;说明：CHDFS 对于数据沉降、删除和回热，需要依赖 COS 对外提供的标准接口，所以生命周期在使用方式上与 COS 相似。&lt;/p&gt;

&lt;p&gt;五、使用方式&lt;/p&gt;

&lt;p&gt;用户可以通过控制台和云 API 来配置生命周期规则，创建回热任务仅支持云 API。&lt;/p&gt;

&lt;p&gt;1、控制台&lt;/p&gt;

&lt;p&gt;进入 CHDFS 控制台，选择具体文件系统，进入生命周期配置页，添加规则，完成生命周期配置，如下图所示：&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/Cloud_Storage_Angel/fbb3501c-b21e-440a-a29e-222bca16137f.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;说明：同时指定沉降和删除规则表示对目标文件先沉降后删除，删除时间必须要大于沉降时间。&lt;/p&gt;

&lt;p&gt;2、云 API&lt;/p&gt;

&lt;p&gt;通过云 API 创建生命周期规则示例：&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/Cloud_Storage_Angel/50d37789-437a-46f4-88b3-95fb5ada644c.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;创建回热任务示例：&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/Cloud_Storage_Angel/be046c9c-217b-416d-9b76-9f1308e1281c.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;说明：支持批量创建回热任务，回热任务需要指定具体文件路径。&lt;/p&gt;

&lt;p&gt;六、计费&lt;/p&gt;

&lt;p&gt;目前，CHDFS 只收取标准存储量和带宽的费用，归档存储量和回热请求暂不收费。&lt;/p&gt;

&lt;p&gt;七、结语&lt;/p&gt;

&lt;p&gt;CHDFS 结合对象存储 COS 无限容量的优势，深耕文件系统元数据管理，规模可扩大至百亿级别，同时配合用户自定义的生命周期策略，最大力度去帮助用户降低 CHDFS 存储成本，满足用户的使用需求。&lt;/p&gt;

&lt;p&gt;关于我们&lt;/p&gt;

&lt;p&gt;云 + 社区「腾讯云存储团队」主页，涵盖了腾讯云存储团队最新动态、团队信息、产品矩阵、技术文档、视频教程等，欢迎关注或留言，给出您的宝贵建议。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/Cloud_Storage_Angel/0aebe29d-7fca-4790-905a-bafa52c6b83b.png!large" title="" alt=""&gt;&lt;/p&gt;</description>
      <author>Cloud_Storage_Angel</author>
      <pubDate>Fri, 26 Feb 2021 12:36:51 +0800</pubDate>
      <link>https://ruby-china.org/topics/40967</link>
      <guid>https://ruby-china.org/topics/40967</guid>
    </item>
    <item>
      <title>腾讯云对象存储 COS 获 Veritas 认证，数据安全能力再升级</title>
      <description>&lt;p&gt;近日获悉，腾讯云对象存储 COS 正式通过 Veritas 备份软件标准化测试，为数据安全再添新助力。&lt;/p&gt;

&lt;p&gt;Veritas 对 COS 的支持已经从底层打通，目前 Veritas 的 NetBackup 和 Backup Exec 备份软件均已认证 COS。这意味着用户只要购买了 COS 的云存储空间，就可以通过 NetBackup/Backup Exec 进行远程数据备份，把数据写入 COS 的存储桶中，也可以在 NetBackup/Backup Exec 上直接访问或删除 COS 的数据，极大的简化了数据备份和使用过程，方便快捷实现数据上云，并能够在几分钟内实现备份容灾。&lt;/p&gt;

&lt;p&gt;Veritas 作为全球最大的多云数据管理平台厂商，一直致力于为客户提供跨平台的数据管理能力。Veritas 连续 15 次荣列 Gartner“数据中心备份和恢复解决方案魔力象限”领导者象限，彰显了 Veritas 在全球高端中型市场和大型企业环境具有较高影响力。Veritas 推出的 NetBackup 是一款统一数据保护解决方案，广泛支持各种工作负载、云和架构，简化了企业数据保护管理，确保关键业务韧性。目前 NetBackup 使用 COS 存储作为备份存储有两种方式，一种是直连方式，支持压缩，限速，加密传输等功能；一种是 CloudCatalyst，支持重删、本地缓存、限速、加密等功能，从 NBU8.3 开始 CloudCatalyst 被整合到 MSDP Cloud 中。&lt;/p&gt;

&lt;p&gt;腾讯云作为国内近年来发展速度最快的云厂商，拥有超过 100 万的开发者。据 Gartner 首次发布的《云基础设施和平台服务》报告，腾讯云是入围本次魔力象限的 7 家国际厂商之一。COS 能提供数据跨多架构、多设备冗余存储，为用户提供异地容灾和资源隔离功能，细粒度的数据存储方式，更有利于数据管理、用户访问与合规。COS 还提供图形化程序、命令行工具、协议工具等多种途径对存储对象进行批量操作，还有能够将存储桶挂载到本地的工具，让用户能像使用本地文件系统一样直接操作 COS。&lt;/p&gt;

&lt;p&gt;随着云计算、大数据、AI 等新技术的发展，数据成为互联网企业重要的资产。但各类意外突发事件，如自然灾害、电力中断、勒索病毒、人为失误等都可能造成数据丢失或损坏，更甚者导致经济损失。因此容灾，特别是基于云端的容灾，对保障数据安全变得尤为重要。&lt;/p&gt;

&lt;p&gt;而现在可以通过 CloudCatalyst 或自建（BYOD）两种方式，帮助用户将去重后的备份数据发送至 COS。CloudCatalyst 可确保备份数据无论是在上云途中，还是在云中静态存储时，均处于优化状态。同时备份数据还可以进一步存储至 COS 的深度归档存储中，COS 深度归档存储费用仅为 0.01 元/GB/月，用户可以在云上享受与磁带存储成本相当的产品体验。&lt;/p&gt;

&lt;p&gt;本次和 Veritas 的强强联合，大大降低了使用 COS 的成本，并显著提高了存储性能。将对象存储 COS 海量存储和异地容灾能力，与 Veritas 强大的重复数据删除技术相结合，可以更好地利用云存储备份，满足灾难恢复或长期数据保留需求。&lt;/p&gt;

&lt;p&gt;对用户来说，通过 Veritas NetBackup/Backup Exec 将数据备份到 COS，无需采买底层硬件，资源按需使用，可灵活扩展和备份管理，且存储空间无上限，能有效简化运维，减少人力成本。并帮助企业快速实现基于云端的备份，降低勒索病毒等各类意外事件影响，同时满足企业数据的超增长与合规要求。&lt;/p&gt;</description>
      <author>Cloud_Storage_Angel</author>
      <pubDate>Fri, 29 Jan 2021 15:06:50 +0800</pubDate>
      <link>https://ruby-china.org/topics/40875</link>
      <guid>https://ruby-china.org/topics/40875</guid>
    </item>
    <item>
      <title>一个小攻略：如何最大化利用青云 QingCloud 特价机型</title>
      <description>&lt;p&gt;最近 &lt;a href="https://www.qingcloud.com/promotion202010/" rel="nofollow" target="_blank" title=""&gt;青云 QingCloud 在搞特价促销&lt;/a&gt;，最便宜的一款主机（VM Instance）已经低至年费只需 89.9 元人民币，味千拉面现在都得 51 块一碗了…，买来之后可以做什么呢？有人搭博客、有人跑  &lt;a href="https://git-scm.com/" rel="nofollow" target="_blank" title=""&gt;Git&lt;/a&gt;、有人做测试，我这里提供一个思路，可以最大程度的榨取这款机器的价值，且解决工作与生活中的实际问题和需求。 &lt;/p&gt;

&lt;p&gt;从 2007 年逐渐兴起的移动互联网让我们每个人手头都有多款电子设备，比如我自己的日常设备： &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Android Phone - 电话（随时）&lt;/li&gt;
&lt;li&gt;iPad Pro - 移动办公辅助设备（差旅）&lt;/li&gt;
&lt;li&gt;Mac Book Pro - 移动办公主力设备（差旅）&lt;/li&gt;
&lt;li&gt;PC with Arch Linux - 固定办公设备（办公室或家）&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;还有更多人在使用 Windows 设备，由此可见日常工作和生活中我们跨设备之广。为了解决在这么多不同厂商、不同操作系统的设备之间保持数据同步及一致，大家条件反射会想到 &lt;a href="https://www.dropbox.com/" rel="nofollow" target="_blank" title=""&gt;Dropbox&lt;/a&gt; 和 &lt;a href="https://pan.baidu.com/" rel="nofollow" target="_blank" title=""&gt;百度网盘&lt;/a&gt;，但是：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;前者在墙外，翻墙是个强技术活儿、且也不适合用来做数据同步、花销高、还有额外 xx 风险…；&lt;/li&gt;
&lt;li&gt;后者存在严重的隐私和用户数据安全问题；&lt;/li&gt;
&lt;li&gt;如果你的数据比较多，免费版将无法支持的了，而付费，则将大大超过 89.9 元。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;著名的开源项目 &lt;a href="https://nextcloud.com/" rel="nofollow" target="_blank" title=""&gt;Nextcloud&lt;/a&gt; 可以很容易地完美解决此需求，而且因为是自部署（self-hosted），所以不存在隐私问题、免费版限制等问题。当然，Nextcloud 绝不仅仅是一个网盘和文件同步功能，通过其插件体系可以很容易实现一个完整的生产力平台。&lt;/p&gt;

&lt;p&gt;以下操作使用的是一台位于 广东 2 区 的 Arch Linux 主机，你可以选择自己喜欢的 Region 和 Linux 分发版。创建主机我就不描述了，随着向导走即可。&lt;/p&gt;
&lt;h2 id="1. 准备工作环境"&gt;1. 准备工作环境&lt;/h2&gt;&lt;h2 id="1.1. EIP"&gt;1.1. EIP&lt;/h2&gt;
&lt;p&gt;主机创建完成之后，需要 EIP（弹性公网 IP 地址）连接互联网。在 &lt;a href="https://console.qingcloud.com/login" rel="nofollow" target="_blank" title=""&gt;Web Console&lt;/a&gt; 导航栏中进入 &lt;strong&gt;网络与 CDN&lt;/strong&gt; -&amp;gt; &lt;strong&gt;公网 IP&lt;/strong&gt;，然后申请一个 IPv4 EIP，绑定到你的主机上即可。&lt;/p&gt;
&lt;h2 id="1.2. Docker"&gt;1.2. Docker&lt;/h2&gt;
&lt;p&gt;修改 pacman 镜像源：&lt;/p&gt;

&lt;p&gt;/etc/pacman.d/mirrorlist&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Server = http://mirrors.tuna.tsinghua.edu.cn/archlinux/$repo/os/$arch
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;刷新操作系统：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pacman -Syyu
reboot
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;安装 Docker：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pacman -S docker
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;配置 Docker Daemon：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/etc/docker/daemon.json
{
    "experimental": true,
    "bridge": "none",
    "registry-mirrors": [
        "https://docker.mirrors.ustc.edu.cn/"
    ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;启动、启用 Docker：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;systemctl start docker
systemctl enable docker
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="2. 运行 nextcloud"&gt;2. 运行 nextcloud&lt;/h2&gt;
&lt;p&gt;创建工作目录：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir -p /srv/nextcloud/{server,data}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;拉取最新稳定版、并启动 nextcloud server：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker pull nextcloud:latest

docker run --name nextcloud --restart unless-stopped \ 
    -v /srv/nextcloud/server:/var/www/html \
    -v /srv/nextcloud/data:/var/www/html/data \
    --network host -d nextcloud:latest
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后打开浏览器，输入地址 &lt;strong&gt;&lt;a href="http://your-eip-address" rel="nofollow" target="_blank"&gt;http://your-eip-address&lt;/a&gt;&lt;/strong&gt;，即可开始对 nextcloud server 进行初始化配置。该模版默认使用 TCP 80 端口，请记得去 &lt;strong&gt;安全&lt;/strong&gt; -&amp;gt; &lt;strong&gt;防火墙&lt;/strong&gt;，确保 TCP 下行 80 端口为开启状态。&lt;/p&gt;

&lt;p&gt;初始化配置很简单，只有三个项目：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;在初始化界面里，创建的第一个用户拥有管理员权限；&lt;/li&gt;
&lt;li&gt;保持 Storage &amp;amp; database 不变；&lt;/li&gt;
&lt;li&gt;取消 (uncheck) Install recommended apps。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;然后点击 &lt;strong&gt;Finish Setup&lt;/strong&gt;，等待完成即可。&lt;/p&gt;
&lt;h2 id="3. 优化 nextcloud"&gt;3. 优化 nextcloud&lt;/h2&gt;
&lt;p&gt;Nextcloud 是一个庞大的系统，可以调教优化的地方非常多，我这里仅仅指出两点比较适合小团体或个人使用的网盘及文件同步功能的优化，毕竟大家在促销时通常也是购买低配置的机型。&lt;/p&gt;
&lt;h2 id="3.1. 禁止没啥用的 apps"&gt;3.1. 禁止没啥用的 apps&lt;/h2&gt;
&lt;p&gt;使用上一步初始化时创建的 nextcloud 管理员账号登陆后，打开 apps 配置页，地址是 &lt;strong&gt;&lt;a href="http://your-eip-address/settings/apps" rel="nofollow" target="_blank"&gt;http://your-eip-address/settings/apps&lt;/a&gt;&lt;/strong&gt;，禁用以下 apps：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Accessibility&lt;/li&gt;
&lt;li&gt;Activity&lt;/li&gt;
&lt;li&gt;Collaborative tags&lt;/li&gt;
&lt;li&gt;Federation&lt;/li&gt;
&lt;li&gt;First run wizard&lt;/li&gt;
&lt;li&gt;Nextcloud announcements&lt;/li&gt;
&lt;li&gt;Privacy&lt;/li&gt;
&lt;li&gt;Recommendations&lt;/li&gt;
&lt;li&gt;Support&lt;/li&gt;
&lt;li&gt;Usage survey&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="3.2. cron job"&gt;3.2. cron job&lt;/h2&gt;
&lt;p&gt;Nextcloud 有一系列的工作是在后台工作的，新建以下两个配置文件：&lt;/p&gt;

&lt;p&gt;/etc/systemd/system/nextcloud-cron.service&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Unit]
Description=Nextcloud cron.php job

[Service]
ExecStart=docker exec --user www-data nextcloud php -f /var/www/html/cron.php
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;/etc/systemd/system/nextcloud-cron.timer&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Unit]
Description=Run Nextcloud cron.php every 10 minutes

[Timer]
OnBootSec=5min
OnUnitActiveSec=10min
Unit=nextcloud-cron.service

[Install]
WantedBy=timers.target
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;启用、启动：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;systemctl daemon-reload
systemctl enable nextcloud-cron.timer
systemctl start nextcloud-cron.timer
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后，以管理员账号登陆 nextcloud，进入 &lt;strong&gt;Settings&lt;/strong&gt; -&amp;gt; &lt;strong&gt;Administration&lt;/strong&gt; -&amp;gt; &lt;strong&gt;Basic settings&lt;/strong&gt; -&amp;gt; &lt;strong&gt;Background jobs&lt;/strong&gt;，选中 &lt;strong&gt;Cron&lt;/strong&gt; 这个项目，即可。&lt;/p&gt;
&lt;h2 id="4. nextcloud 客户端"&gt;4. nextcloud 客户端&lt;/h2&gt;
&lt;p&gt;Nextcloud 客户端 支持市面上全部的操作系统，包括 Windows、Linux、Mac OS X、Android、iOS、iPadOS，从其官网或各移动应用市场均可下载安装。&lt;/p&gt;
&lt;h2 id="5.（可选的）极致省钱操作"&gt;5.（可选的）极致省钱操作&lt;/h2&gt;
&lt;p&gt;合理使用青云 QingCloud 的一些免费政策，花点儿技术配置时间，可以天长日久的极致省钱，以下举两个例子。&lt;/p&gt;
&lt;h2 id="5.1. 使用 IPv6 EIP"&gt;5.1. 使用 IPv6 EIP&lt;/h2&gt;
&lt;p&gt;若你的日常网络环境（办公室、家庭等）有 IPv6 支持的话，强烈建议在以上配置结束后使用 IPv6 的 EIP 地址替代 IPv4 的，因为青云 QingCloud IPv6 地址是免费的。目前在中国多数情况下，IPv6 是默认部署了的，以北京电信为例，其 ADSL 宽带和手机 4G 网络都已良好支持 IPv6，且局方默认均开启。&lt;/p&gt;

&lt;p&gt;注意，由于 IPv6 地址无法直接在浏览器地址栏使用，所以必须使用 FQDN 域名解析到 IPv6 地址，青云 QingCloud 提供了免费的 &lt;a href="https://www.qingcloud.com/products/dns/" rel="nofollow" target="_blank" title=""&gt;DNS 权威解析服务&lt;/a&gt;，位于 Web Console 导航栏的 &lt;strong&gt;网络与 CDN&lt;/strong&gt; -&amp;gt; &lt;strong&gt;DNS&lt;/strong&gt;。&lt;/p&gt;
&lt;h2 id="5.2. 使用对象存储"&gt;5.2. 使用对象存储&lt;/h2&gt;
&lt;p&gt;青云 QingCloud 的对象存储在 10GB 容量以内是免费的，而且跟位于同一 Region 的主机之间的流量是内网，速度稳定高速、且完全免费，在 Web Console 导航栏中进入 &lt;strong&gt;存储&lt;/strong&gt; -&amp;gt; &lt;strong&gt;对象存储&lt;/strong&gt;，然后创建一个 bucket。&lt;/p&gt;

&lt;p&gt;Nextcloud 可以支持 &lt;a href="https://en.wikipedia.org/wiki/Amazon_S3" rel="nofollow" target="_blank" title=""&gt;S3&lt;/a&gt; 对象存储作为 external storage，而青云 QingCloud 对象存储完全兼容 &lt;a href="https://docs.qingcloud.com/qingstor/s3/" rel="nofollow" target="_blank" title=""&gt;兼容 S3&lt;/a&gt; APIs，只需以下三步操作：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;在管理员界面的 &lt;strong&gt;apps&lt;/strong&gt; 里启用 &lt;strong&gt;External storage support&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;在 &lt;strong&gt;Settings&lt;/strong&gt; -&amp;gt; &lt;strong&gt;Administration&lt;/strong&gt; -&amp;gt; &lt;strong&gt;External storages&lt;/strong&gt; 中选中 &lt;strong&gt;All user to mount external storage&lt;/strong&gt;、并确保 Amazon S3 是被选中的子项。&lt;/li&gt;
&lt;li&gt;在 &lt;strong&gt;Settings&lt;/strong&gt; -&amp;gt; &lt;strong&gt;Personal&lt;/strong&gt; -&amp;gt; &lt;strong&gt;External storages&lt;/strong&gt; 中选择 &lt;strong&gt;Amazon S3&lt;/strong&gt;，然后输入相应的青云 QingCloud 对象存储的信息。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;这样就多了 10GB 免费空间了。&lt;/p&gt;

&lt;p&gt;更多玩法，大家可以挖掘，have fun !&lt;/p&gt;</description>
      <author>arron</author>
      <pubDate>Sat, 23 Jan 2021 19:45:59 +0800</pubDate>
      <link>https://ruby-china.org/topics/40845</link>
      <guid>https://ruby-china.org/topics/40845</guid>
    </item>
    <item>
      <title>null</title>
      <description>&lt;p&gt;null&lt;/p&gt;</description>
      <author>ccmywish</author>
      <pubDate>Tue, 19 Jan 2021 23:32:06 +0800</pubDate>
      <link>https://ruby-china.org/topics/40831</link>
      <guid>https://ruby-china.org/topics/40831</guid>
    </item>
    <item>
      <title>基于腾讯云存储网关 CSG 实现视频在线转码分发</title>
      <description>&lt;p&gt;一、背景&lt;/p&gt;

&lt;p&gt;随着越来越多的传统业务云化和云端业务发展，数据上云和云端数据处理领域的需求爆发式增长。腾讯云存储网关 CSG 提供一键部署开箱即用的便捷模式，深度结合 COS 对象存储生态，为用户提供方便快捷的数据上云通道，有效满足业务数据备份、数据上云和云上数据处理的需求。&lt;/p&gt;

&lt;p&gt;腾讯云存储网关 CSG 提供文件语义到对象存储语义的转换，依托 COS 对象存储的海量存储能力，使用户通过本地文件协议即可读写云端 COS 数据，无需对现有业务做任何侵入式开发，即可使业务获得接近无限容量的文件系统使用能力，借助 CSG 热数据缓存能力，业务数据上云后业务侧还能够高效对 COS 里的业务数据进行后续加工处理。&lt;/p&gt;

&lt;p&gt;二、业务场景&lt;/p&gt;

&lt;p&gt;下文将以视频转码分发业务场景为例，带您了解 CSG 在该场景的应用。&lt;/p&gt;

&lt;p&gt;业务侧生产出原始视频流 H264 文件，通过 CSG 将 H264 文件素材同步到 COS，同步后再将 H264 文件作为输入继续转码成 TS 视频文件，最终将 TS 文件的 COS 访问链接发布到客户端侧，供各类客户端访问。&lt;/p&gt;

&lt;p&gt;业务架构示意图：
&lt;img src="https://l.ruby-china.com/photo/Cloud_Storage_Angel/f0ebd662-2836-4438-893f-446988cb1e80.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;1、依据业务规模部署存储网关 CSG，通过腾讯云存储网关控制台一键部署或者通过腾讯云 COS 控制台一键部署。&lt;/p&gt;

&lt;p&gt;CSG 控制台一键部署网关
&lt;img src="https://l.ruby-china.com/photo/Cloud_Storage_Angel/1930cbd5-dc7f-4b16-a208-add705e7b110.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;COS 控制台一键部署网关
&lt;img src="https://l.ruby-china.com/photo/Cloud_Storage_Angel/046e006d-d59a-4f04-9e1d-049e2894c603.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;2、业务服务器中挂载 CSG 文件系统。&lt;/p&gt;

&lt;p&gt;使用下列命令实现 NFS v4.0 挂载
&lt;img src="https://l.ruby-china.com/photo/Cloud_Storage_Angel/6ae99906-4601-4f78-b8af-c09b02732783.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;3、业务上传原始 h264 视频文件到 CSG 文件系统素材目录。
&lt;img src="https://l.ruby-china.com/photo/Cloud_Storage_Angel/08dd1a51-62f3-43e9-b4e0-295c5658e3b1.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;4、业务通过 CSG 文件系统，直接对素材目录中的文件执行转码操作，输出新文件到转码输出目录。通过 CSG 执行转码操作和本地磁盘执行转码操作在默认情况下性能接近，当使用自定义 SSD 机型的 CSG 时，将获得比本地普通磁盘更高的 IO 性能，单台 CSG 吞吐量可达 1GB/s。
&lt;img src="https://l.ruby-china.com/photo/Cloud_Storage_Angel/89dc78c7-6e46-4610-b721-6fa86740689a.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;5、原始素材和转码后的文件均通过 CSG 同步到 COS 存储桶，实现素材和输出文件同步到云端 COS。
&lt;img src="https://l.ruby-china.com/photo/Cloud_Storage_Angel/95a1fcd3-d200-48e1-9ea9-94ef04e87134.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;6、通过 SCF 云函数感知 COS 存储桶转码目录路径中的对象创建事件，将对象创建事件发布到业务指定 CMQ 消息队列。
&lt;img src="https://l.ruby-china.com/photo/Cloud_Storage_Angel/0384b8ed-2d1c-47d6-bb35-548158225c8b.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;SCF 云函数示例
&lt;img src="https://l.ruby-china.com/photo/Cloud_Storage_Angel/48dfe244-c45a-4103-94c8-4812ff2bc488.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;7、业务服务通过业务指定 CMQ 消息队列进行消费，获取转码文件已成功上传到 COS 的事件信息，将对应文件的 COS 加速域名发布到客户端服务，使客户端能够通过 COS 加速域名下载浏览最终文件。
&lt;img src="https://l.ruby-china.com/photo/Cloud_Storage_Angel/27a756ab-ac23-4c44-86e8-5cbd6ddc60a0.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;三、结语&lt;/p&gt;

&lt;p&gt;存储网关 CSG 依托 COS 对象存储生态，为业务提供接近无限容量文件系统的使用能力。&lt;/p&gt;

&lt;p&gt;通过存储网关的热数据缓存能力，业务能够对流程中前一步上传的文件进行高效加工处理，直接在 CSG 生产出后续业务流程所需的数据，并通过 CSG 将这些数据自动同步至 COS。&lt;/p&gt;

&lt;p&gt;整个数据上云和数据处理过程，均通过本地文件系统接口来操作，无需业务做侵入式改造，即可使业务数据上云并对数据进行加工处理，并可直接在云端生产出最终结果数据，结合后续 SCF 云函数和 CMQ 消息队列的腾讯云平台能力，可轻松和业务服务联动将云端 COS 数据链接分发至用户业务客户端。&lt;/p&gt;</description>
      <author>Cloud_Storage_Angel</author>
      <pubDate>Fri, 15 Jan 2021 17:53:12 +0800</pubDate>
      <link>https://ruby-china.org/topics/40813</link>
      <guid>https://ruby-china.org/topics/40813</guid>
    </item>
    <item>
      <title>使用腾讯云对象存储 COS 作为 Velero 后端存储，实现集群资源备份和还原</title>
      <description>&lt;p&gt;Velero（以前称为 Heptio Ark）是一个开源工具，可以安全地备份和还原，执行灾难恢复以及迁移 Kubernetes 集群资源和持久卷，可以在 TKE 集群或自建 Kubenetes 集群中部署 Velero 用于：&lt;/p&gt;

&lt;p&gt;1、备份集群资源并在丢失的情况下进行还原。&lt;/p&gt;

&lt;p&gt;2、将集群资源迁移到其他集群。&lt;/p&gt;

&lt;p&gt;3、将生产集群资源复制到开发和测试集群。&lt;/p&gt;

&lt;p&gt;Velero 工作原理图如下图所示，当用户执行备份命令时，调用自定义资源 API 创建备份对象（1），BackupController 控制器 watch 到生成的备份对象时（2）执行备份操作（3），备份完成后将备份的集群资源和存储卷快照上传到 Velero 的后端存储（4 和 5）；类似的，当执行还原操作时，Velero 会将指定备份对象的数据从后端存储同步到 Kubernetes 集群完成还原工作。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2020/991feac8-2d57-4002-8a1e-ca3c37404807.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;下面介绍使用腾讯云对象存储 COS 作为 Velero 后端存储实现集群备份和还原的操作步骤。&lt;/p&gt;

&lt;p&gt;一、前提条件&lt;/p&gt;

&lt;p&gt;1、已注册腾讯云账户；&lt;/p&gt;

&lt;p&gt;2、已开通 COS 服务；&lt;/p&gt;

&lt;p&gt;3、已创建 Kubernetes 集群，集群版本 v1.10 或更高版本，集群可正常使用 DNS 和 互联网服务。&lt;/p&gt;

&lt;p&gt;二、配置存储&lt;/p&gt;

&lt;p&gt;1、创建 COS 存储桶&lt;/p&gt;

&lt;p&gt;在 COS 控制台为 Velero 创建一个对象存储桶来存储备份。&lt;/p&gt;

&lt;p&gt;通过 COS 控制台为存储桶设置访问权限。对象存储 COS 支持设置两种权限类型：&lt;/p&gt;

&lt;p&gt;1）公共权限设置：为了安全起见，推荐存储桶权限类别为私有读写。&lt;/p&gt;

&lt;p&gt;2）用户权限设置：主账号默认拥有存储桶所有权限（即完全控制），另外 COS 支持添加子账号有数据读取、数据写入、权限读取、权限写入，甚至完全控制的最高权限。&lt;/p&gt;

&lt;p&gt;由于需要对存储桶进行读写操作，为示例子账号授予数据读取、数据写入权限，如下图所示：
&lt;img src="https://l.ruby-china.com/photo/2020/c3e3aeb6-e12a-49ef-8050-3d48ec329995.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;2、获取存储桶访问凭证&lt;/p&gt;

&lt;p&gt;Velero 使用与 AWS S3 兼容的 API 访问 COS，需要使用一对访问密钥 ID 和密钥创建的签名进行身份验证，在 S3 API 参数中，access_key_id 字段为访问密钥 ID，secret_access_key 字段为密钥。&lt;/p&gt;

&lt;p&gt;在腾讯云访问管理控制台新建和获取 COS 授权的示例子账号的腾讯云密钥 SecretId 与 SecretKey，如下图。其中 SecretId 值对应 access_key_id 字段，SecretKey 值对应 secret_access_key 字段。
&lt;img src="https://l.ruby-china.com/photo/2020/7d49f67a-4a6e-4dd8-9366-87cf95484d31.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;根据上述对应关系在本地目录中创建 Velero 所需的凭证配置文件 credentials-velero：
&lt;img src="https://l.ruby-china.com/photo/2020/b8e683fa-9946-4eb2-bbe0-6d45afa36068.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;三、安装 Velero&lt;/p&gt;

&lt;p&gt;下载最新官方发行的 Velero 压缩包到集群环境中，本示例以撰写此文档时最新版本 v1.5.2 为例。
&lt;img src="https://l.ruby-china.com/photo/2020/beea93ff-8fda-475c-8b18-eecfe25aaf02.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;提取压缩包，压缩包中包含 Velero 命令行执行文件和一些示例文件。
&lt;img src="https://l.ruby-china.com/photo/2020/d1f70795-d37d-4de3-9fc3-3c3abf3525ac.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;将 velero 可执行文件从解压后的目录迁移到系统环境变量目录下直接使用，这里移至 /usr/bin 目录。 
&lt;img src="https://l.ruby-china.com/photo/2020/b95256d5-f8fd-4596-b82e-51525511af7c.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;执行下面 Velero 安装命令，创建 Velero 和 restic 工作负载以及其他必要的资源对象。
&lt;img src="https://l.ruby-china.com/photo/2020/16aeed57-f961-4438-bc9a-743f9e273489.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;参数说明：&lt;/p&gt;

&lt;p&gt;--provider：声明使用的 Velero 插件类型。&lt;/p&gt;

&lt;p&gt;--plugins：使用 S3 API 兼容插件“velero-plugin-for-aws”。&lt;/p&gt;

&lt;p&gt;--bucket：在腾讯云 COS 创建的存储桶名。&lt;/p&gt;

&lt;p&gt;--secret-file：访问 COS 的访问凭证文件，见上面创建的“credentials-velero”凭证文件。&lt;/p&gt;

&lt;p&gt;--use-restic：使用开源免费备份工具 restic 备份和还原持久卷数据。Velero 支持使用免费开源备份工具 restic 备份和还原 Kubernetes 存储卷数据 (不支持 hostPath 卷)，这种集成是 Velero 备份功能的补充，建议开启。&lt;/p&gt;

&lt;p&gt;--default-volumes-to-restic：使用 restic 来备份所有 Pod 卷，前提是需要开启 --use-restic 参数。&lt;/p&gt;

&lt;p&gt;--backup-location-config：备份存储桶访问相关配置。&lt;/p&gt;

&lt;p&gt;--region：兼容 S3 API 的 COS 存储桶地区，例如创建地区是广州的话，region 参数值为“ap-guangzhou”。&lt;/p&gt;

&lt;p&gt;--s3ForcePathStyle：使用 S3 文件路径格式。&lt;/p&gt;

&lt;p&gt;--s3Url：COS 兼容的 S3 API 访问地址，请注意不是创建的 COS 存储桶的公网访问域名，而是要使用格式为 &lt;a href="https://cos" rel="nofollow" target="_blank"&gt;https://cos&lt;/a&gt;..myqcloud.com 的 URL，例如地区是广州的话，参数值为“&lt;a href="https://cos.ap-guangzhou.myqcloud.com" rel="nofollow" target="_blank"&gt;https://cos.ap-guangzhou.myqcloud.com&lt;/a&gt;”。&lt;/p&gt;

&lt;p&gt;另外还有其他安装参数可以使用 velero install --help 查看，比如不想备份存储卷数据的话可以设置 --use-volume-snapshots=false 来关闭存储卷数据快照备份。&lt;/p&gt;

&lt;p&gt;执行上面的安装命令后，安装过程如下图所示：
&lt;img src="https://l.ruby-china.com/photo/2020/3aecd144-7210-400c-a6fd-ce3005af72fa.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;安装命令执行完成后，等待 Velero 和 restic 工作负载就绪后，查看配置的存储位置是否可用。&lt;/p&gt;

&lt;p&gt;执行 velero backup-location get 命令查看存储位置状态，显示“Avaliable”，则说明访问 COS 正常，如下图所示：
&lt;img src="https://l.ruby-china.com/photo/2020/e3bd0133-b991-4c0a-8f2b-7fc13aae0e78.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;至此，Velero 安装完成。&lt;/p&gt;

&lt;p&gt;四、Velero 备份还原测试&lt;/p&gt;

&lt;p&gt;在集群中使用 helm 工具创建一个具有持久卷的 minio 测试服务，minio 安装⽅式请参阅 minio 安装，在此示例中，已经为 minio 服务绑定了负载均衡器，可以在浏览器中使用公网地址访问管理页面。
&lt;img src="https://l.ruby-china.com/photo/2020/3a1326ee-793f-4664-94fe-bc9fe11139d8.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;登录 minio Web 管理页面，上传一些测试的图片数据，如下图：
&lt;img src="https://l.ruby-china.com/photo/2020/22f66bbd-298b-4985-b136-f64b489458e8.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;接下来使用 Velero 备份，可以直接备份集群中的所有对象，也可以按类型，名称空间和/或标签过滤对象，本示例使用下面命令仅备份 default 命名空间下所有资源：
&lt;img src="https://l.ruby-china.com/photo/2020/18ef56e5-16e1-48ff-981e-8c66eaee282a.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;使用 velero backup get 命令查看备份任务是否完成，当备份任务状态是“Completed”时，错误数为 0，说明备份任务完成且没发生任何错误，备份过程如下图：
&lt;img src="https://l.ruby-china.com/photo/2020/f233fb42-dd0b-417f-a0a6-9fde0849ed8b.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;此时我们删掉 minio 所有资源，包括它的 PVC 持久卷，如下图：
&lt;img src="https://l.ruby-china.com/photo/2020/8a70a3ad-4810-4238-b67b-2fb92be71cd2.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;删掉 minio 资源后，我们就可以测试使用之前的备份来还原被删除的 minio 资源了，先临时将备份存储位置更新为只读模式（这可以防止在还原过程中在备份存储位置中创建或删除备份对象）： 
&lt;img src="https://l.ruby-china.com/photo/2020/2f99f412-4c7a-4005-a2b7-483cd41ddae4.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;修改 Velero 的存储位置的访问权限为“ReadOnly”，如下图所示：
&lt;img src="https://l.ruby-china.com/photo/2020/5480c52e-567d-410f-bb49-ecbf81194b9b.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;现在使用刚才 Velero 创建的备份 "default-backup" 来创建还原任务：
&lt;img src="https://l.ruby-china.com/photo/2020/db5db893-c62c-49cb-8c9b-9239c9059362.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;同样可以使用 velero restore get 来查看还原任务的状态，若还原状态是“Completed”，错误数为 0，则说明还原任务完成，还原过程如下图：
&lt;img src="https://l.ruby-china.com/photo/2020/a97acca9-b837-4f15-897a-66b4b62c45a6.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;还原完成后，可以看到之前被删除的 minio 相关资源已经还原成功了，如下图：
&lt;img src="https://l.ruby-china.com/photo/2020/667f18cf-0012-4ddd-b144-f73546c3fa52.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;在浏览器上登录 minio 的管理页面，可以看到之前上传的图片数据还在，说明持久卷的数据成功还原，如下图：
&lt;img src="https://l.ruby-china.com/photo/2020/2f2719eb-4640-438e-aa7c-f7bc48d6fc85.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;还原完成后，不要忘记把备份存储位置恢复为读写模式，以便下次备份任务成功使用： 
&lt;img src="https://l.ruby-china.com/photo/2020/20f63dcf-5f98-4b5d-b84f-22633482287b.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;五、Velero 卸载&lt;/p&gt;

&lt;p&gt;若想在集群中卸载 velero，使用下面命令即可完成卸载。
&lt;img src="https://l.ruby-china.com/photo/2020/3550ed2d-977b-4b84-8b8e-5f093babdd2d.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;六、总结&lt;/p&gt;

&lt;p&gt;在本文中，我们简单介绍了 Kubernetes 集群资源备份工具 Velero，展示了如何配置腾讯云对象存储 COS 来作为 Velero 的后端存储，并成功实践了 minio 服务资源和数据的备份和还原操作。&lt;/p&gt;

&lt;p&gt;七、参考&lt;/p&gt;

&lt;p&gt;Velero 官网：&lt;a href="https://velero.io/" rel="nofollow" target="_blank"&gt;https://velero.io/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Restic 工具介绍：&lt;a href="https://github.com/restic/restic" rel="nofollow" target="_blank"&gt;https://github.com/restic/restic&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Minio 安装：&lt;a href="https://github.com/minio/charts" rel="nofollow" target="_blank"&gt;https://github.com/minio/charts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;restic 限制：&lt;a href="https://velero.io/docs/v1.5/restic/#limitations" rel="nofollow" target="_blank"&gt;https://velero.io/docs/v1.5/restic/#limitations&lt;/a&gt;&lt;/p&gt;</description>
      <author>Cloud_Storage_Angel</author>
      <pubDate>Thu, 24 Dec 2020 15:39:47 +0800</pubDate>
      <link>https://ruby-china.org/topics/40737</link>
      <guid>https://ruby-china.org/topics/40737</guid>
    </item>
  </channel>
</rss>
