晨曦's Blog

This is a window to the soul

虽然度娘是一个垮掉的搜索引擎,但是谁叫它在强国是垄断的存在呢。谈谈 Hexo 部署在 Github Pages 怎么提交 Sitemap 给百度。

Sitemap

因为 Github Pages 禁止百度爬虫所以这里我们不做过多的说明,无疑这种方式是行不通的

自动推送

目前在用的一种推送方式

1
自动推送是百度搜索资源平台为提高站点新增网页发现速度推出的工具,安装自动推送JS代码的网页,在页面被访问时,页面URL将立即被推送给百度

安装方式也很简单,只需要在页面中加入以下 JS 即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<script>
(function(){
var bp = document.createElement('script');
var curProtocol = window.location.protocol.split(':')[0];
if (curProtocol === 'https') {
bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
}
else {
bp.src = 'http://push.zhanzhang.baidu.com/push.js';
}
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(bp, s);
})();
</script>

主动推送 (实时)

我们重点来说说主动推送

首先我们这里需要安装一下生成 sitemap 的包

1
npm i hexo-generator-baidu-sitemap -s

新建文件 push_sitemap_to_baidu.php,这里我们通过 PHP 来实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?php
// 解析xml
$file = "./public/baidusitemap.xml";
$xml = simplexml_load_file($file);
$urls = array();
foreach ($xml as $key => $value) {
$url = array();
$url = (array) $value->loc;
$urls[] = current($url);
}
// 调用百度API
$api = 'http://data.zz.baidu.com/urls?site=https://www.jakehu.me&token=***';
$ch = curl_init();
$options = array(
CURLOPT_URL => $api,
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POSTFIELDS => implode("\n", $urls),
CURLOPT_HTTPHEADER => array('Content-Type: text/plain'),
);
curl_setopt_array($ch, $options);
$result = curl_exec($ch);
// 返回结果记录
$time = date("Y-m-d H:i:s");
$content = $time . " --- " . $result . PHP_EOL;
$file = "push_sitemap.log";
$fp = fopen($file, "a+") or die("fail to open the file");
fwrite($fp, $content);
fclose($fp);

最后会在根目录下生成 push_sitemap.log 日志文件

然后改造 package.json 如下

1
2
3
"scripts": {
"push": "hexo cl && hexo g && gulp && hexo d && php -f push_sitemap_to_baidu.php"
}

这条命令包含了清理生成压缩部署推送Sitemap,关于 gulp 压缩部分可看这里【点击查看】

最后我们可以直接运行命令进行部署和推送 npm run push,或者将 push 改为 start 直接运行 npm start 即可

Headless Chrome

什么是 Headless Chrome

Chrome59 中开始搭载 Headless Chrome。这是一种在无需显示 headless 的环境下运行 Chrome 浏览器的方式。从本质上来说,就是不用 Chrome 浏览器来运行 Chrome 的功能!它将 ChromiumBlink 渲染引擎提供的所有现代 Web 平台的功能都带入了命令行。

intoli

开始安装之前我们来了解一下这家公司

我们(intoli)是一家在数据采集,处理和分析方面具有深厚专业知识的咨询机构。

安装

intoli 在其博客上介绍了几种安装 Headless Chrome 的方式,我们采用如下方式安装:

1
curl https://intoli.com/install-google-chrome.sh | bash

安装完成提示:

1
Successfully installed Google Chrome!

intoli 安装文档

运行 chrome

我们可以通过如下命令来启动 Chrome,同时将博客截图保存

1
google-chrome-stable --no-sandbox --headless --disable-gpu --screenshot https://www.jakehu.me

Chromedriver

chromedriver 可以前往淘宝镜像下载,同时通过下面命令进行验证:

1
2
3
4
./chromedriver
Starting ChromeDriver 73.0.3683.68 (47787ec04b6e38e22703e856e101e840b65afe72) on port 9515
Only local connections are allowed.
Please protect ports used by ChromeDriver and related test frameworks to prevent access by malicious code.

如果有如上输出则表示驱动正常运行

最近心血来潮想鼓捣鼓捣爬虫于是玩起了 pyspider,不过在启动的时候却遇到了一些小问题。

1
2
3
ValueError: Invalid configuration:
- Deprecated option 'domaincontroller': use 'http_authenticator.domain_controller' instead.

最后定位在了 wsgidav3.x 问题,pyspider 会默认安装 wsgidav3.x,解决办法为先把 3.x 卸载,再装 2.xpip install wsgidav 会默认安装 2.x 我安装的是 2.4.1

1
2
pip uninstall wsgidav  
pip install wsgidav

如果安装的 wsgidav 本还是 3.x, 可以在卸载这个版本之后,在安装命令后面加上具体版本号

1
python -m pip install wsgidav==2.4.1

前记

Kubeadm 是一个工具,通过提供 kubeadm initkubeadm join 来作为创建 Kubernetes 集群的最佳实践 “快速路径”

简单理解就跟 Docker swarm 差不多吧,KubeadmGA 版本都已经发布了,那还等什么呢?

部署

资源版本
  1. CentOS 7.6 64
  2. Kubernetes version: v1.13.2
  3. Docker version 18.06

这里为什么使用 Docker 18.06 是因为 kubeadm now properly recognizes Docker 18.09.0 and newer, but still treats 18.06 as the default supported version.

所以我们默认还是使用 18.06

服务器

这里我们使用 CentOS 7.6 64,同时测试环境为阿里云服务器

IP Address Hostname CPU Memory
172.16.1.86 Master 2C 4G
172.16.1.87 Node1 2C 4G
172.16.1.88 Node2 2C 4G

这里注意一下服务器系统,目前官方已支持 Ubuntu 16.04+Debian 9CentOS 7RHEL 7

配置

关闭防火墙

1
2
3
setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
systemctl stop firewalld && systemctl disable firewalld

设定 /etc/hosts

1
2
3
172.16.1.86 Master
172.16.1.87 Node1
172.16.1.88 Node2

禁用 Swap

1
swapoff -a && sysctl -w vm.swappiness=0

将配置中 net.bridge.bridge-nf-call-iptables 被设为 1

1
2
3
4
cat <<EOF >  /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
安装 Docker

在 3 台服务器上都安装上 Docker,此次实验 Docker 版本:Docker version 18.06

Centos Docker 安装文档

安装完成启动 Docker

1
systemctl enable docker.service
安装 K8s

在 3 台服务器上配置 YUM 源为阿里镜像源

1
2
3
4
5
6
7
8
9
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

您需要在每台机器上都安装以下的软件包:

  1. kubeadm: 用来初始化集群的指令。
  2. kubelet: 在集群中的每个节点上用来启动 podcontainer 等。
  3. kubectl: 用来与集群通信的命令行工具。
1
2
yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
systemctl enable kubelet && systemctl start kubelet

版本:Kubernetes version: v1.13.2

Master

Master 节点上配置 kubelet 所需的 cgroup 驱动

1
2
3
cat <<EOF >  /var/lib/kubelet/kubeadm-flags.env
KUBELET_EXTRA_ARGS=--cgroup-driver=cgroupfs
EOF

需要重启 kubelet

1
2
systemctl daemon-reload
systemctl restart kubelet

k8s.gcr.io 镜像本地化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
kubeadm config images list //查看所需要的镜像

// 编辑脚本从hub获取镜像
vim k8s.sh

#!/bin/bash
docker pull coredns/coredns:1.2.6
docker tag coredns/coredns:1.2.6 k8s.gcr.io/coredns:1.2.6
docker rmi coredns/coredns:1.2.6
images=(
kube-apiserver:v1.13.2
kube-controller-manager:v1.13.2
kube-scheduler:v1.13.2
kube-proxy:v1.13.2
pause:3.1
etcd:3.2.24
)
for imageName in ${images[@]} ; do
docker pull mirrorgooglecontainers/$imageName
docker tag mirrorgooglecontainers/$imageName k8s.gcr.io/$imageName
docker rmi mirrorgooglecontainers/$imageName
done

// 编辑脚本权限
chmod +x k8s.sh

// 执行脚本
./k8s.sh

初始化 Master

1
kubeadm init --kubernetes-version=v1.13.2 --pod-network-cidr=10.244.0.0/16

配置 kubectl 认证信息

1
2
3
4
5
6
7
8
# 非root用户
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

# root用户
export KUBECONFIG=/etc/kubernetes/admin.conf
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile

安装网络插件 flannel

1
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
Node

Node 镜像本地化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 编辑脚本从hub获取镜像
vim k8s.sh

#!/bin/bash
images=(
kube-proxy:v1.13.2
pause:3.1
)
for imageName in ${images[@]} ; do
docker pull mirrorgooglecontainers/$imageName
docker tag mirrorgooglecontainers/$imageName k8s.gcr.io/$imageName
docker rmi mirrorgooglecontainers/$imageName
done

// 编辑脚本权限
chmod +x k8s.sh

// 执行脚本
./k8s.sh

将节点加入集群

1
kubeadm join 172.16.1.86:6443 --token xxx --discovery-token-ca-cert-hash xxx
Dashboard

未完待续…


题外话:

安装过程中可以用 tail -f 100 /var/log/messages 查看日志,便于找到问题所在

前记

说说本地环境 Deepin 15.8Python2Python3 共存

问题

问题如下:

1
2
3
4
5
6
$ pip3
Traceback (most recent call last):
File "/usr/local/bin/pip3", line 7, in <module>
from pip._internal import main
ModuleNotFoundError: No module named 'pip._internal'

1
2
3
4
5
6
$ pip
Traceback (most recent call last):
File "/usr/local/bin/pip", line 7, in <module>
from pip._internal import main
ModuleNotFoundError: No module named 'pip._internal'

pippip3 均不可使用

解决

1
2
3
4
5
6
7
8
9
10
11
$ sudo easy_install pip
Searching for pip
Best match: pip 10.0.1
Adding pip 10.0.1 to easy-install.pth file
Installing pip script to /usr/local/bin
Installing pip3.6 script to /usr/local/bin
Installing pip3 script to /usr/local/bin

Using /usr/local/lib/python2.7/dist-packages
Processing dependencies for pip
Finished processing dependencies for pip

完美解决

公共包的处理

解决方案是将公共包打包在 runner 服务器上,其他模块打包时自动应用公共包.gitlab-ci.yml 如下:

1
2
3
4
5
6
stages:
- deploy
maven-build:
stage: deploy
script:
- mvn install

注册中心地址

Eureka 地址应为 http://[service name]:[port]/eureka

切记 http 协议

runner 提权

gitlab-runner 装好后并不能通过 CI 执行,因为 gitlab-runner 是通过 gitlab-runner 用户及用户组运行的,并不是 ROOT 权限,所以这里就需要对 gitlab-runner 用户进行提权

说到提权这里说两种方式

  1. usermod
1
2
3
usermod -ag root gitlab-runner // 将gitlab-runner用户加入root用户组

// 不过这种方式我没有成功,我使用的是第二种方式
  1. /etc/passwd
1
2
3
4
vi /etc/passwd
gitlab-runner:x:997:993:GitLab Runner:/home/gitlab-runner:/bin/bash // 修改前
gitlab-runner:x:0:0:GitLab Runner:/home/gitlab-runner:/bin/bash // 修改后


未完待续

microsoft remote desktop for mac

根据【官方文档】所示,两种方式获取

  1. Mac 应用应用商店下载 (只支持美区)
  2. Mac beta 版,通过【appcenter】下载

Mos

一个用于在 macOS 上平滑你的鼠标滚动效果或单独设置滚动方向的小工具,让你的滚轮爽如触控板

Mos

Redis 客户端

Redis 客户端众多,安利两款自己用过,还觉得不错的

AnotherRedisDesktopManager

Medis


未完待续

LCN 简介

  1. LCN 分布式事务框架的核心功能是对本地事务的协调控制,框架本身并不创建事务,只是对本地事务做协调控制
  2. 因此该框架与其他第三方的框架兼容性强,支持所有的关系型数据库事务,支持多数据源,支持与第三方数据库框架一块使用
  3. 在使用框架的时候只需要添加分布式事务的注解即可,对业务的侵入性低

LCN 核心步骤

  1. 创建事务组,是指在事务发起方开始执行业务代码之前先调用 TxManager 创建事务组对象,然后拿到事务标示 GroupId 的过程
  2. 添加事务组,添加事务组是指参与方在执行完业务方法以后,将该模块的事务信息添加通知给 TxManager 的操作
  3. 关闭事务组,是指在发起方执行完业务代码以后,将发起方执行结果状态通知给 TxManager 的动作。当执行完关闭事务组的方法以后,TxManager 将根据事务组信息来通知相应的参与模块提交或回滚事务

LCN 事务控制原理

LCN 事务控制原理是由事务模块 TxClient 下的代理连接池与 TxManager 的协调配合完成的事务协调控制 TxClient 的代理连接池实现了 javax.sql.DataSource 接口,并重写了 close 方法,事务模块在提交关闭以后 TxClient 连接池将执行” 假关闭” 操作,等待 TxManager 协调完成事务以后在关闭连接

阿里云 GTS 全局事务服务

  1. 全局事务服务(Global Transaction Service,简称 GTS)是一款高性能、高可靠、接入简单的分布式事务中间件,用于解决分布式环境下的事务一致性问题
  2. GTS 支持 DRDS、RDS、MySQL 等多种数据源,可以配合 EDAS 和 SpringCloud 等微服务框架使用, 兼容 MQ 实现事务消息。通过各种组合,可以轻松实现分布式数据库事务、多库事务、消息事务、服务链路级事务等多种业务需求

GTS 模拟场景演示

性能

GTS 通过大量创新,解决了事务 ACID 特性与高性能、高可用、低侵入不可兼得的问题。单事务分支的平均响应时间在 2ms 左右,3 台服务器组成的集群可以支撑 3 万 TPS 以上的分布式事务请求

LCN 性能参考:http://springcloud.cn/view/374 在众多开源分布式事务框架中,LCN 性能是处于前列的

LCN 总结

优点:

  • 性能优秀
  • 可靠性强
  • LCN 实现的分布式事务处理模式,编码复杂性和入侵代码量低

缺点:

  • 需额外部署 tx-manager 服务节点
  • 由于需要 lock 资源这种处理方式,如果集中更新某几个热门商品时,LCN 的性能衰减量大于 TCC 模式
  • 服务超时时,会造成其他服务的资源被锁住,比如支付服务超时过程中,相关商品库存会一直无法操作
  • 不支持 SpringCloud 2.0.0 及以上版本(目前已通过修改源码实现支持)

GTS 总结

优点:

  • 性能优秀 (有淘宝双十一作为示例)
  • 可靠性强
  • 代码入侵性小(相比 LCN 多一点)
  • 支持 SpringCloud 2.0.0 及以上版本

缺点:

  • 无法在本地进行测试
  • 只能在阿里云内网使用,或者购买专有云

前记

博客 hexo 一直部署在 Github Pages,方便、稳定非常 nice,但是最近发现打开博客的速度比较慢。于是想着能否通过多部署,或者国内 CDN 加快访问速度

加速方案

  1. 利用 Gitee Pages 作为国内部署,但是 Gitee Pages 免费版不支持 https,遂作罢
  2. 利用 Coding Pages 作为国内部署,支持 Let's Encrypt https,但发现所加速的 IP 均为国外 IP,有时也比较的慢,于是尝试在国内找 cdn 加速就有了下面方案的对比
  3. 百度云:免费版不支持 https,遂作罢
  4. 腾讯云:没有免费额度,支持上传自有证书,遂作罢
  5. 七牛 CDN:免费 10G 额度,免费版不支持 https,遂作罢
  6. 又拍云 (在用方案,目前最完美方案):支持 Let's Encrypt 加入又拍云联盟 10G 空间 + 15G 流量额度

后记

加速过后速度杠杠的

前记

最近由于项目比较大而且附件比较多,在服务器上选择了外挂 Nas 盘符来存储项目文件

目前服务器和 Nas 都是用的阿里的服务,这里说一下阿里在 Linux 中自动挂载的注意事项,在 /etc/fstab 配置文件中添加以下命令:

1
fid-xxxx.cn-hangzhou.nas.aliyuncs.com:/ /mnt  nfs4 vers=4.0,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,_netdev,noresvport 0 0

重点来了,请注意:

命令中的 fid-xxxx.cn-hangzhou.nas.aliyuncs.com 为挂载点的域名

我第一次的时候就把 xxxx.cn-hangzhou.nas.aliyuncs.com 替换为了挂载点的域名,而保留了 fid

实现

按阿里官方说明为重启时自动挂载 NAS 文件系统,如果需要及时生效可以运行以下命令而不用重启:

1
2
sudo mount -a
-a:将 /etc/fstab 中定义的所有档案系统挂上