安装docker

当前仅展示apt方式安装,离线安装方式不展示

清理历史残留

如果系统有预装docker或者先前安装过,先卸载干净在安装

1
2
3
4
5
6
## 第一次安装时输出为空
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt remove $pkg; done

## 如果以前有安装过docker,相关数据可以删除掉
sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd

apt安装

设置代理

由于docker被gfw屏蔽,访问时需要使用vpn,这里使用先前搭建的ss服务

新建apt.conf

1
sudo vi /etc/apt/apt.conf

添加proxy配置,默认源地址配置直连,如此后续配置docker源后,使用apt update便可直接访问

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Acquire::http::Proxy "http://127.0.0.1:8118";
Acquire::http::Proxy {
archive.ubuntu.com DIRECT;
security.ubuntu.com DIRECT;
cn.archive.ubuntu.com DIRECT;
mirrors.tuna.tsinghua.edu.cn DIRECT;
}
Acquire::https::Proxy "http://127.0.0.1:8118";
Acquire::https::Proxy {
archive.ubuntu.com DIRECT;
security.ubuntu.com DIRECT;
cn.archive.ubuntu.com DIRECT;
mirrors.tuna.tsinghua.edu.cn DIRECT;
}
阅读全文 »

前言

一般情况下,日常开发我只使用vagrant跟virtualbox,但后面想搭建一个k8s环境学习,需要一个免费、高性能、便于管理的虚拟机管理软件

综合考虑了下现在市面上的虚拟机管理软件

  1. virtualbox 的磁盘性能太差,nat网络所有虚拟机都是同一个IP:10.0.2.15,其他方面也不考虑了
  2. parallel desktop 太贵太黑心
  3. vmware 价格也不便宜还很吃电脑资源
  4. hyper-v 管理界面太难用,同时无法固定虚拟机IP

最终我选择组装一台台式机,安装了ubuntu系统,并在上面安装使用kvm虚拟机

cpu是amd 7700,8核心16线程;32GB内存;暂时不需要用到显卡;PC在路由器做了MAC跟IP的绑定,方便使用ssh

由于virt-manager太难用,最后选择cockpit作为kvm虚拟机管理软件

kvm安装

前置工作

确认cpu开启虚拟化功能

1
2
# 一般是cpu的核心数量
egrep -c '(vmx|svm)' /proc/cpuinfo

安装kvm

安装kvm以及依赖软件

1
2
3
4
5
6
7
8
9
10
11
12
sudo apt install qemu-system-x86 libvirt-daemon-system virtinst \
virt-manager virt-viewer ovmf swtpm qemu-utils guestfs-tools \
libosinfo-bin tuned

# 开机启动
sudo systemctl enable libvirtd

# 验证安装
sudo virt-host-validate qemu

# 如果有使用window的需要,可以下载virtio
wget https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/archive-virtio/virtio-win-0.1.240-1/virtio-win-0.1.240.iso
阅读全文 »

前言

由于国内恶劣的网络环境,作为一名频繁访问外网的Web开发者,不得不自建一个VPN服务,以下简单介绍Shadowsocks的搭建过程。

单纯的ss流量会迅速被gfw识别到并屏蔽,因此使用ss时需要增加obfs用以混淆欺骗gfw,可以极大程度减小被屏蔽的风险。当然,如果你用的是比较出名的服务器供应商,如bandwagon的服务器,那么被屏蔽的机会也很大。

服务端使用的一键安装脚本twist由于开发者已经放弃维护长时间,目前只有参考作用,如果你有耐心,也可以自己修改后再使用,也就跟下面的服务端搭建教程一样。搞完是真的累,太渣了,太需要提高自己的编程水平,写一个一体化的软件包才行

服务端

twist脚本

服务端使用的是twist脚本,里面集成了Shadowsocks+simple-obfs+fail2ban以及相关依赖包,使用shell编写,感兴趣的可以看看源代码,下载地址如下

1
https://github.com/forestbat/Twist

下载后,脚本添加执行权限

1
chmod +x twist

切换到root账户,twist执行需要

1
su - root
阅读全文 »

以下简单介绍如何在C语言层面使用PHP类

对象

创建一个PHP对象,对象类似关联数组,对象之上可关联任意多个函数

1
2
3
4
5
6
7
PHP_FUNCTION(makeObject) {
object_init(return_value);

// 添加属性
zend_update_property_string(NULL, return_value, "prop1", strlen("prop1"), "val1");
zend_update_property_long(NULL, return_value, "prop2", strlen("prop2"), 123);
}

调用函数并打印结果var_dump(makeObject());,输出如下

1
2
3
4
5
6
object(stdClass)#1 (2) {
["prop1"]=>
string(3) "val1"
["prop2"]=>
int(123)
}
阅读全文 »

从19年开始,ss流量已经能被gfw识别并屏蔽,原本打算切换到v2ray,但配置混淆需要域名反而会暴露出更多信息,此外,网上一篇文章指出v2ray开发者失联的同时一项v2ray流量识别的专利被注册,因此决定放弃v2ray并转向另一个被linus盛赞的wireguard。

wireguard是非常简单、现代化、快速的vpn,使用最新的加密技术,udp传输,支持ip漫游等。wireguard没有服务端、客户端的区分,每一台设备都是一个peer

安装

添加wireguard的PPA源

1
2
3
sudo add-apt-repository ppa:wireguard/wireguard
sudo apt update
sudo apt install wireguard

wireguard作为linux内核模块方式加载,内核更新wireguard也会自动重新编译,重启系统或使用modprobe开启模块

1
sudo modprobe wireguard

检查wireguard模块是否成功加载,成功输出与下面类似

1
2
3
4
vagrant@bionic:~$ lsmod | grep wireguard
wireguard 221184 0
ip6_udp_tunnel 16384 1 wireguard
udp_tunnel 16384 1 wireguard

生成keys

wireguard提供了两个命令行工具wg以及wg-quick,使用wg生成公钥和私钥

1
2
umask 077
wg genkey | sudo tee /etc/wireguard/privatekey | wg pubkey | sudo tee /etc/wireguard/publickey

类似ssh,需要为每台设备生成一对publickey/privatekey

阅读全文 »

本文将简单介绍资源类型、资源的创建、访问、销毁操作。不再建议使用资源类型,使用类更为合适

资源类型

zval可以表示大部分的PHP数据类型,但有一样不能很好的表示其结构:指针。由于不透明的结构、无法使用传统运算符进行操作等,使得指针在PHP的表示变得困难。因此PHP用一个特殊的标记表示指针:资源,为了使资源标记具有意义,必须先注册到zend engine才能使用。

在头文件定义结构体php_test_person以及资源名称,放置在#define语句后,PHP_MINIT_FUNCTION(test);之前

1
2
3
4
5
6
typedef struct {
zend_string *name;
zend_long age;
} php_test_person;

#define PHP_TEST_PERSON_RES_NAME "Person Data"

源文件定义le_*全局变量,MINIT阶段注册,用于获取资源类型、字面意义名称、析构函数

1
2
3
4
5
6
int le_test_person;

PHP_MINIT_FUNCTION(test)
{
le_test_person = zend_register_list_destructors_ex(NULL, NULL, PHP_TEST_PERSON_RES_NAME, module_number);
}
阅读全文 »

PHP扩展开发第二章,主要介绍函数参数获取、zval数据类型、数组及数组遍历以及$GLOBALS全局变量访问

函数参数

扩展自定义函数不需要声明形参,Zend Engine会给每个函数传递一个参数列表zend_execute_data *execute_data,函数参数通过宏块ZEND_PARSE_PARAMETERS_STARTZEND_PARSE_PARAMETERS_END获取,当然,旧的方法zend_parse_parameters也可以使用,只是会更麻烦点

下面示例函数将接收参数name以及打印的次数t_param并打印name

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
PHP_FUNCTION(test)
{
// 参数1
zend_string *name;
// 参数2
zend_long t_param = 0;
int times = 1;

// 最低可接收1个参数,最多2个
ZEND_PARSE_PARAMETERS_START(1, 2)
Z_PARAM_STR(name)
Z_PARAM_OPTIONAL
Z_PARAM_LONG(t_param)
ZEND_PARSE_PARAMETERS_END();

// 判断是否有传递默认值
if (ZEND_NUM_ARGS() == 2) {
times = (int) (t_param < 1 ? 1 : t_param);
}

// 打印
for (int i = 0; i < times; i++) {
php_printf("Hello %s", ZSTR_VAL(name));
}
RETURN_TRUE;
}

常用的有数据类型以及参数获取方法有下

Variable Type Macro
zend_bool Z_PARAM_BOOL
zend_long Z_PARAM_LONG
double Z_PARAM_DOUBLE
zend_string * Z_PARAM_STR
char * Z_PARAM_STRING
zval * Z_PARAM_RESOURCE
zval * Z_PARAM_ARRAY
zval * Z_PARAM_OBJECT
zval * Z_PARAM_ZVAL
阅读全文 »

flamegraph是一款可视化工具,用户分析程序堆栈调用,x轴堆栈轨迹,y轴堆栈深度,x轴长度越长,占用更多cpu时间。下面简单介绍如何使用xdebug以及flamegraph生成火焰图

准备工作

配置xdebug参数

1
2
3
4
5
xdebug.trace_output_name = xdebug.trace.%t.%s
xdebug.trace_enable_trigger = 1
xdebug.trace_output_dir = /tmp
xdebug.trace_enable_trigger_value = "<secret key>"
xdebug.trace_format=1

下载flamegraph,git clone https://github.com/brendangregg/FlameGraph.git,放置在任意位置

flamegraph

获取堆栈数据

请求页面/接口url,在url后面增加?XDEBUG_TRACE=<secret key>,获取php堆栈数据 curl http://youdomain.com?XDEBUG_TRACE=<secret key>,如果是命令行命令,则在php命令后使用参数php -d xdebug.auto_trace=1

转换堆栈数据

1
./stackcollapse-xdebug.php /tmp/xdebug.trace.1579703170._data_www_yii2_web_index_php.xt > out.folded

生成火焰图

1
./flamegraph.pl out.folded > out.svg

示例

yii2 flamegraph example

参考

How to generate PHP Flamegraphs
Flame Graphs visualize profiled code

很长的一段时间,被xubuntu下的一个monospace字体显示问题困扰着,在网上找了很多方法也没有解决问题,在一次误打误撞的情况下解决了,简单把自己问题的过程记录下来,希望给一些小伙伴们帮助

问题描述

xubuntu下monospace在浏览器以及vscode下显示异常,具体如下图所示

浏览器chrome/firefox下的monospace

monofont display incorrect in browser

vscode下的monospace

monofont display incorrect in vscode

网上搜索结果大部分指示,是由于libfreetype6 2.8.1-2ubuntu2的一个bug导致,需要升级到最新的libfreetype2.9或者降级到libfreetype2.8.0,按照搜索的文档进行libfreetype的升级/降级后,显示效果依旧,问题没有得到解决

解决过程

在我放弃治疗后过了一段时间,突然想起,一直以来都忽略了验证linux的字体信息。首先,获取显示异常的字体font-family,如下图

browser get font family

使用fc-match验证字体

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ fc-match monospace
DejaVuSansMono.ttf: "DejaVu Sans Mono" "Book"

$ fc-match consolas
DejaVuSansMono.ttf: "DejaVu Sans Mono" "Book"

$ fc-match Menlo
DejaVuSans.ttf: "DejaVu Sans" "Book"

$ fc-match "PingFang SC"
DejaVuSans.ttf: "DejaVu Sans" "Book"

$ fc-match "Microsoft YaHei"
NotoSansCJK-Regular.ttc: "Noto Sans CJK SC" "Regular"

可以看到Menlo、”PingFang SC”、”Microsoft YaHei”的实际字体跟monospace并不一致,抱着死马当活马医的心态,编辑字体配置文件~/.config/fontconfig/fonts.conf,内容如下,

1
2
3
4
5
6
7
8
<?xml version='1.0'?>
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
<fontconfig>
<alias>
<family>Menlo</family>
<prefer><family>DejaVu Sans Mono</family></prefer>
</alias>
</fontconfig>

退出,重新登录,发现这个困扰了很久的问题终于解决,如下图

monofont the correct view

vscode可以通过更改font-family恢复正常的显示效果

注意

ubuntu/xubuntu、中文/英文的系统默认的字体会有些许差异,以上的操作可能不一定生效,可以新增~/.config/fontconfig/conf.d/00-menlo.conf

1
2
3
4
5
6
7
8
9
10
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<alias binding="same">
<family>Menlo</family>
<accept>
<family>DejaVu Sans Mono</family>
</accept>
</alias>
</fontconfig>

参考文档

[Ubuntu 18.04 LTS] Font not rendering properly
Ubuntu 18.04 LTS Font not rendering properly
Why doesn’t fc-match respect my match and edit rule for Courier when it does for Consolas?

工欲善其事必先利其器,xdebug是php开发的一个杀手级利器,vagrant是一款非常便捷的虚拟机管理工具,两者搭配有时会出现一些奇怪的问题,近期在重新配置开发环境时,出现xdebug连不上的异常情况,花了些时间才找到问题并解决,记录下解决问题的过程,希望能帮助到一些小伙伴

问题及解决过程

异常情况

xdebug配置后,客户端多次请求,vscode均无任何反应。检查服务端、客户端配置,确认没有差错;监测网络数据,只有初次请求数据,无结果返回

客户端/服务器配置信息

服务器是vagrant + ubuntu 18.04 + PHP 7.4,客户端是Windows 10,编辑器是vscode

初始xdebug配置如下

1
2
3
4
5
6
7
8
[xdebug]
xdebug.remote_enable = 1
xdebug.remote_autostart = 1
xdebug.remote_port = 9001
xdebug.remote_handler = "dbgp"
xdebug.remote_mode = req
xdebug.remote_connect_back = 1
xdebug.overload_var_dump=0

vscode配置launch.json如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"version": "0.2.0",
"configurations": [
{
"name": "Listen for XDebug",
"type": "php",
"request": "launch",
"port": 9001,
"pathMappings": {
"/data/example": "D:\\data\\example"
},
"log": true
}
]
}

开启xdebug日志监测

1
xdebug.remote_log=/tmp/xdebug.log

再次请求,获取日志数据如下

1
2
3
4
5
6
7
[140114918627520] Log opened at 2019-09-04 11:49:00
[140114918627520] I: Checking remote connect back address.
[140114918627520] I: Checking header 'HTTP_X_FORWARDED_FOR'.
[140114918627520] I: Checking header 'REMOTE_ADDR'.
[140114918627520] I: Remote address found, connecting to 192.168.33.1:9001.
[140114918627520] E: Time-out connecting to client (Waited: 200 ms). :-(
[140114918627520] Log closed at 2019-09-04 11:49:00

日志显示服务端有正常向客户端9001端口发起连接,但客户端无响应导致超时,检查客户端防火墙无异常

最后,在谷歌上找到一个类似的问题,发现问题与vagrant有关,具体问题描述见参考文档链接

解决方法

1
2
3
; 移除 xdebug.remote_connect_back = 1
; 添加
xdebug.remote_host=10.0.2.2

重启php-fpm,再次测试,vscode可连接xdebug,问题解决

参考文档

How to configure Xdebug in PhpStorm through Vagrant
xdebug Time-out connecting to client

0%