分类
linux

重置 MariaDB root 密码

以我最常用的 Ubuntu 为例,记录如何重置 MariaDB root 密码。MariaDB 是 MySQL 原作者在 MySQL 闭源之后的再起之作,基本能完全兼容 MySQL。在我的 Ubuntu 上,它的大部分命名都沿用 MySQL。

1. 停掉 mysql 服务

$ service mysql stop

2. 以特殊方式启动 mysql

使用 --skip-grant-tables 可以跳过用户权限检查,让你没有密码也能连接。此时为了避免安全问题,可以加上 --skip-networking,防止有人此时通过网络连接你的数据库。在本地环境下差别不大。

$ sudo mysqld_safe --skip-grant-tables --skip-networking &

这一步可能会启动失败,导致下一步连接时报错:ERROR 2002 (HY000): Can’t connect to local MySQL server through socket ’/var/run/mysqld/mysqld.sock’ (2),此时,可以这样修正:

$ sudo mkdir /var/run/mysqld
$ sudo chown mysql /var/run/mysqld

3. 连接数据库

$ mysql -u root

正常情况下就连上了。

4. 重置密码

mysql> FLUSH PRIVILEGES;
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'new_password';

5. 重启 mysql

按照参考文档里介绍的做法,需要

$ sudo kill `cat /var/run/mysqld/mysqld.pid`
# 或
$ sudo kill `/var/run/mariadb/mariadb.pid`

不过我实际操作的时候只要把(2)开启的进程关掉就好了。然后重启 mysql 服务:

$ service mysql restart

6. 完成

尝试一下连接,应该可以成功了:

$ mysql -uroot -p

7. Ghost 连接

虽然命令行连接成功,但是 ghost start 仍然报错,经查,是 Ghost 的数据库连接方式有点问题,修改 config.production.json,加入一行配置即可,大体如下:

{
  "client": "mysql",
  "connection": {
    ....
    "socketPath": "/var/run/mysqld/mysqld.sock",
  }
}
分类
招聘

突发招聘: Zine 诚聘 Web 前端开发工程师 全职远程

早上刷推,看到一家全职远程公司招聘 Web 前端开发工程师,叫 Zine,做编辑器产品。心想正好可以水一篇更新,就转载一下吧。

我跟这家公司并不熟,不过经常在 V2 上看到他们家的消息,应该还是可以的,有自己的产品,有五险一金。感兴趣、并且有定力的同学可以试一试。

投了再说:

hr@auramarker.com

关于投简历的建议:

  1. 开篇写一段100~150字的自我描述,让招聘方对你有一个概括的了解。同时你会更像一个人,而不是某个数字。
  2. 针对对方的 JD 强调自己的优势,比如类似的技术背景、产品开发经验、或者深度用户
  3. 对职业经历的描述要体现自己的价值,哪怕只是参与者,不要写“负责完成领导交付的任务”

完整的 JD 在这里:

【全职远程】 Zine 诚聘 Web 前端开发工程师

V2上的帖子:

「全职远程」 Zine 诚聘 Web 前端 开发者

分类
github

GitHub 开放自定义 Profile 功能

GitHub 有一个个人简介(Profile)页面,比如我,我的用户名是 meathill,我的个人简介就是 https://github.com/meathill。这个页面和 GitHub Pages 有所不同,后者是完全自定义的,想放啥都可以;Profile 页面只体现我们在 GitHub 上的状态。

不过很多同学并不满足 GitHub Pages,还想定义这个页面;现在 GitHub 闲钱也比较多,可以改进这些痒点;于是乎,自定义 profile 就诞生了。

使用方法:

  1. 创建一个与用户名相同的仓库,比如我,就是 meathill 仓库
  2. 创建时,你就能看到小提示了:(因为我已经创建过仓库,所以有错误提示,正常没有)
  3. 如提示所写,你只需要编辑这个仓库里的 README 文件,就会自动更新页面上的内容
  4. 更新后的效果如下:

感觉还不错,近期找工作的同学赶紧用起来吧,是个不错的加分项。

分类
linux

Ubuntu 20.04 科学上网

闲言少叙,直奔主题。

0. 服务器

首先,你得先准备个服务器,这方面略过不谈。

1. 客户端

接下来,下载客户端。

我用的是 shadowsocks-qt5,先在 https://github.com/shadowsocks/shadowsocks-qt5/releases 这个页面下载打包好的 AppImage 文件。

右键点击文件,在“权限”选项卡里勾选“允许文件作为程序执行”,然后双击运行,配置服务器信息。配置完成,点击“连接”,顺利的话,就会显示连接成功。

在命令行里输入 gnome-session-properties,会启动如下图所示的“启动应用程序首选项”,把刚才下载的 AppImage 路径添加进来,这样每次启动 ss 客户端都会自动启动了。

启动应用程序首选项

2. 生成 pac

安装genpac

pip install genpac

Ubuntu 20.04 默认 python版本是 3,所以可以使用 pip3 替代上面的 pip。

使用在线的 gfwlist

genpac --pac-proxy "SOCKS5 127.0.0.1:1080" --gfwlist-proxy="SOCKS5 127.0.0.1:1080" --gfwlist-url=https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt --output="autoproxy.pac"

使用离线的 gfwlist

如果你的机器没有完成配置,暂时无法访问到 gfwlist,也可以先想办法下载到这个文件,然后离线生成。

genpac --pac-proxy "SOCKS5 127.0.0.1:1080" --gfwlist-proxy="SOCKS5 127.0.0.1:1080" --gfwlist-local=你的路径/gfwlist.txt --output="autoproxy.pac"

3. 配置服务器

Ubuntu 安装时就集成了 Apache2,并且默认也会启动它,所以直接把刚才生成的 pac 文件放在 /var/www/html/ 目录下,就能通过 http://localhost/autoproxy.pac 访问到。

不过我不喜欢用 apache,一般都会用 nginx 或者 openresty 取代之。好在默认情况下,nginx 的 web 服务目录也是 /var/www/html,所以只要卸载 apache 然后重新安装 nginx 即可。另外因为这个服务只为使用 pac 文件,所以可以不用换源。

sudo apt remove apache2
sudo apt update
# 安装 openresty 需要的系统依赖
sudo apt-get -y install --no-install-recommends wget gnupg ca-certificates
# 添加 key
wget -O - https://openresty.org/package/pubkey.gpg | sudo apt-key add -
# 添加 openresty 官方源
echo "deb http://openresty.org/package/ubuntu $(lsb_release -sc) main" \
    | sudo tee /etc/apt/sources.list.d/openresty.list
# 在更新一次,然后安装
sudo apt update
sudo apt install openresty
sudo service openresty start

然后访问 http://localhost/autoproxy.pac,如果能打开,就说明配置成功。

4. 启动全局配置

如果,打开“设置”,找到“网络”,打开“网络代理”,选择“自动”,然后填入上面说的 pac 地址即可。

5. 在其它应用里完成配置

比如,打开 Firefox,在“首选项”里找到“网络设置”,然后选择“使用系统代理设置”即可。

分类
电子产品

Ubuntu 20.04 配置 TP-WDN5200H 无线网卡

前情提要:朋友赞助了 AMD 2950x + 技嘉 x399 MEG Creation,我配上其它组件,装了台新电脑。接下来把老电脑收拾一下,装上 Ubuntu 20.04,打算补齐 x86 64 Linux 平台。

结果卡在无线网卡配置上,Ubuntu 无法识别和使用。我的无线网卡是 TP-Link 的 WDN5200H 免驱 USB 网卡,我直接用型号搜索,很容易就找到介绍安装教程

原来这个网卡同时集成了一块小 U 盘,里面是驱动程序,方便没有网络的人安装。但是在 Ubuntu 下,会优先把它识别成 U 盘(但是我也没找到盘符),所以无线网络不工作。解决方案就是先安装驱动,然后用 usb_modeswitch 切换工作模式,然后系统就会把它识别成无线网卡,然后就可以了。

但在我这里,这套操作行不通,切换设备的时候,上面都一样,但最后会报错:

Use interface number 0
 with class 255
Error: can't use storage command in MessageContent with interface 0; interface class is 255, expected 8. Abort.

我用上面的错误信息作为关键词搜索,只能找到各种关于 huawei modem 的讨论,解决不了问题。折腾很久,我突然注意到,我的网卡 ID 似乎和教程里不太一样,我的是 obda:c811,而教程里是 obda:1a2b(分号前是设备id,分号后是产品id),是不是这个原因呢?我以 0bda:c811 作为关键词,很快找到这个答案

原来核心原因在于原先的驱动是基于 4.x 内核的,从 19.04 开始,Ubuntu 内核已经升级到 5.x,所以要用新驱动。所以我按照帖子里的指示,安装了新驱动。一番折腾之后,还是不行……

眼看周末过去,没时间继续折腾了,我只有到京东下单了一款 m2 接口的 Intel AX200 无线网卡(含蓝牙)——据说 Intel 网卡都是免驱的,而且 m2 接口肯定没有集成 U 盘这种幺蛾子。

周一,拿到新网卡,插上。果然,Intel 网卡就是免驱,工作正常;但是,我没买天线,而这个鬼网卡没有天线是绝对不能工作的(客服告诉我可以试试,不行再买天线,我……),于是我只好再下单了一套天线。然后我无意打开 Wi-Fi 一看,WTF,这是啥,Rtl8821CU?不就是我的 TP-WDN5200H 么?原来我昨天其实就弄好了,只是没有重启,没有生效……

至此,问题解决。

分类
wp

Jetpack 的流量统计好像被墙了

从5月23日开始,从 WP 后台的 Jetpack 统计看起来,我的博客访问量大跌。

一开始我以为是 CDN 的问题,拉着同事研究了半天,没有找到证据。然后检查了 DNS 解析统计,似乎也正常。最后想起来看 GA。从 GA 的数据来看,似乎访问量并没有什么变化。那么只好猜测是 Jetpack 的统计出问题,很多访问没有统计到。

不过我觉得多半是误伤,毕竟 Jetpack 作为 WordPress 的产品,很容易被“误伤”,而且在国内也没多少人用,不必像 GA 这样还要留点余地。可惜以后我没法很容易的看到统计数据了。

分类
npm

使用 GitHub Registry 托管私有 NPM 源

我厂有不少私有仓库,都是日常开发中提炼出来的,在几个项目中共享,比如 UI、Vuex、网络请求(axios 封装)等。以前的主要形式是使用 npm 安装 GitHub 仓库,即

npm i openresty/some-repo

这样 npm 会自动去 GitHub 查找对应的仓库,然后 clone 下来完成安装。项目中的 .npmignore 文件也会正常生效,安装后的目录会忽略不需要的文件。这样做的好处就是简单,只要仓库存在,安装依赖的系统有足够的权限(比如 ssh key),就能顺利安装。在过去的三年时间里,我们一直都这样做。

但是这样会有一些问题:

  1. package-lock.json 里记录的是 commit hash,只看这个值无法判断版本,npm 也没法使用版本号解决依赖冲突的问题。换言之,比如 A 仓库需要 C 仓库的 1 版本,B 仓库需要 C 仓库的 2 版本,那么就只能同时安装两个版本,因为 npm 无法判断两个版本是否兼容。
  2. 安装的时候要走 git clone,下载量很大,速度很慢,经常被同事吐槽。也会影响 CI 的效率。
  3. git 仓库里要提交编译后的代码,一方面浪费时间和空间,另一方面大量编译后的代码也影响 code review

所以,考虑之后决定改用 GitHub Registry。GitHub Registry 是 GitHub 提供的私有源,感兴趣的同学可以访问这个页面了解详情。这个服务需要收费,不过我厂本来就是 Team 用户,额度比较富裕,所以并没有阻力。

经过一段时间的摸索,终于搞成了,下面简单说一下做法。

对依赖项目

修改 package.json,把项目名称改成 @openresty/some-repo,即“@公司名/仓库名”。然后增加 publishConfig 字段,设置源为 GitHub registry:

{
  "publishConfig": {
    "registry": "https://npm.pkg.github.com/"
  },
}

接下来,正常使用 npm publish 发布依赖即可。不过在发布之前,最好使用 .npmignore 忽略掉开发时的源文件和配置文件,一方面这些文件对于其它项目的开发没有价值,另一方面无论是存储还是下载消耗流量,都要收费,能省则省嘛。

对业务项目

因为这些依赖仓库都是私有项目,所以我们先得解决身份认证的问题。GitHub 提供了 Personal access tokens 方式,生成 token 后,添加到 ~/.npmrc 文件即可:

//npm.pkg.github.com/:_authToken=<TOKEN>

接下来,在业务项目中,添加 .npmrc 文件,指名依赖源:

registry=https://registry.npmjs.org/
@openresty:registry=https://npm.pkg.github.com

这段配置分两部分:其它域的依赖,直接从 npm 的源下载;@openresty 域下的依赖,从 GitHub Registry 下载。

最后,正常使用 npm i @openresty/some-repo 安装依赖即可。


最后的最后附上修改前后的效果对比,可以看出,改造后效果明显:

国内修改前real 0m39.543s
user 0m17.768s
sys 0m3.944s
阿里云
修改后real 0m16.450s
user 0m15.204s
sys 0m3.380s
阿里云
国外修改前real 0m49.350s
user 0m22.352s
sys 0m4.144s
阿里云
修改后real 0m30.807s
user 0m15.780s
sys 0m3.936s
阿里云
分类
生活

一些近况

4月28日晚上,我在家跳 Just Dance,大概跳了 4 首歌,结果第二天早上起床,左脚踝肿了。我猜测是扭伤,因为前几天光脚跳舞,感觉很粘,做动作比较困难,所以28日特地穿了袜子,光滑了很多。我左脚本就有伤,怀疑旧伤复发。

但是我没有特别在意,觉得似乎不太影响行动,有点大学时候崴了一下那种感觉。于是该遛狗遛狗,该出门出门。晚上伤势突然加重,甚至把我疼醒了。次日起床,脚踝肿得更加严重。我开始怀疑是痛风,因为我尿酸一直偏高。

经过冰敷+云南白药,两日后渐渐消肿,不太影响行动。但是没高兴多久,肩膀又痛起来,也是夜里突发,又把我疼醒了。这次觉得惨了,多半是痛风。

然后赶紧去医院诊治,测了尿酸,好像并不太高。但是血糖因为前阵子的疏忽,百达杨停药,我自己麻痹大意,空腹高到12.5,糖化8.7,已经明显进入发病状态。骨科大夫说,糖尿病人多半会有肩周炎,关节莫名其妙的疼痛也很常见,所以怀疑我并不是痛风,也不是扭伤,而是血糖控制不好导致多发关节炎。

所以,没办法,赶紧控糖吧。首先请内分泌大夫调整药物剂量,我也重新定时定起来,保证按时吃药;其次百达杨性价比太低不再用,但是类似的药还是用起来,这次换上诺合力,在我身上效果明显,食量大减,我本身血糖也高,并不会觉得不舒服;再次,小区里的健身房办张卡,尽量每天都锻炼一下子。

经过一个月努力,现在空腹能维持在 6.1 附近,偶尔能正常;餐后如果体育锻炼,能降到 7.8 以下,不锻炼8附近,算基本控制住。接下来就是坚持,顺便把体重减一减。等到放了暑假,有空去住下院,好好检查一番,希望到时候能都正常。

哎,这身体真是一刻都不能大意啊……


诺合力在我身上表现不错,且已入医保,需要减肥又控制不住嘴巴的同学可以去医院咨询一下专业医师。(此段文字不构成用药建议)

分类
vue

webpack 入口是 vue 文件时,无法合并 CSS

在多页网站中合并 CSS 是很常见的优化手法。一般来说,CSS 体积不会太大,使用同一份 CSS,改进用户点击链接后的加载速度,大部分收益都大于多加载几 K CSS 带来的损耗。

对于 UI 库来说也是如此,用统一的样式库,减少 import 时的心智负担,也是性价比很高的做法。

最开始我在 UI 库的入口文件里 export 所有组件,然后在其它仓库里用 import {component} from 'my-components' 使用组件。后来通过分析得知,这样做无法 tree-shaking,而且会导致组件库的重复引用,即 A import B,B import C,那么无论 A 里有没有用到 C(比如用到 B 的一个小功能 b1,它不依赖 C),都会把 C 的代码打包进去。

通过研读 Webpack 的 tree-shaking 文档,我得知也没有什么好办法可以规避这个问题,毕竟 JS 很灵活,你也不知道哪个开发者会搞个 eval('const myRequire = require'),如果要识别解析分辨所有情况太复杂,所以选择最保守的策略:认不出来具体功能的代码都给你带上。(早年我写 NerveNet 的时候,就是想不通这里怎么搞,最后坑掉了。早知道大家都选择绕开,说不定我的 NerveNet 也能如愿写出来了……)

总之,目前 lodash 的做法比较常见且能解决问题,即增加多入口,为每个可能用到的函数都打包独立的函数。这样需要引用那个就引用哪个,不用担心把整个 lodash 都打包进去。

于是我就立项开始重构我厂的几个前端库。然后很快就卡在 UI 库上面:无法生成合并过的 CSS 文件。Google 许久没有结果,吃饭前我灵机一动:vue-loader 必须搭配 VueLoaderPlugin 才能正确打包,会不会这个过程有 bug,导致如果我的入口都是 Vue 单文件组件,就会没法正确合并 CSS 文件。

然后我就测试了一下,代码大约如下:

// a.js
import './a.styl'

// b.js
import './b.styl'

可以生成合并过的 CSS 文件。与之相较,这样的 Vue 单文件组件就不行:

// a.vue
<style lang="stylus">
body
  font-size 16px
</style>

// b.vue
<style lang="stylus">
body
  color red
</style>

但是,同样是 vue 单文件组件,样式使用 import 的方式导入,就没问题:

// a.vue
<script>
import './a.styl';
</script>

// b.vue
<script>
import './b.styl';
</script>

现在可以确定是 vue-loader 或者 VueLoaderPlugin 有问题。不过最近身体欠佳,每天要花很多时间锻炼,另外还欠下不少坑要填,所以暂时没空去翻 issue 或者提 issue。哪位同学看见了,愿意帮忙的,可以搞一下,也算参与 开源社区建设了,功德无量。

分类
前端

Font Awesome 发布 Duotone 字体,支持双颜色

无意中看到 Font Awesome 发布了 Duotone 双色字体,感觉很神奇,我还不知道 WebFont 竟然支持多种颜色,于是赶紧看了看。

首先,这是旧闻,实际上,去年,也就是2019年7月30日,Font Awesome 就发布了 Duotone。

关于 Duotone 的介绍,大家可以看这篇官方博客:Introducing Duotone。借张图直观地展现 Duotone 的效果:

然后我就很好奇它们是怎么实现的,据我所知 WebFont 不支持多颜色。研究了半天,发现原来是这样:

2019年5月30日,Font Awesome 发布了 Font Awesome Kits(工具包)。Kits 是一个 JS,用来取代之前直接使用 CSS 引用字体的方式。这样做有几个好处:

  1. 根据字体使用情况按需加载
  2. 可以在客户端管理缓存,避免重复下载图标
  3. 可以自动更新图标,跟 Font Awesome 发布同步
  4. 可以帮助开发者处理可用性问题(关于这一点,GitHub 曾经发布过一篇博客,解释他们为什么要从 Icon Font 切换回 图标:https://github.blog/2016-02-22-delivering-octicons-with-svg/
  5. 可以更快应用新技术,比如 HTTP2,SRI 等

上面几个好处都是 Font Awesome 官博《Introducing Font Awesome Kits》中列出来的,还有一个好处它们没说:可以修改 DOM。Duofont 正是藉此实现双色的。打开开发者工具,我们可以看到,所有图标 <i class="fad fa-*"></i> 都被替换成了 inline <svg>,包含两个图层,自然可以通过 CSS 控制颜色等样式。

这个思路很有意思,布局也一步一步规划的很好,虽然不知道最终效果如何,但还是学到不少东西。

Font Awesome 提供免费版,我一直在用。付费版一年 $99,我觉得还是贵了点,所以一直没用,有需求的同学应该试一下。