grpc-go: 客户端与服务器之间双向证书验证通信

  • 生成根证书(ca.key, ca.crt)
%> openssl genrsa -out ca.key 2048
%> openssl req -new -x509 -days 3650 \
     -subj "/C=CN/L=Shanghai/O=grpc/CN=grpc.me"
     -key ca.key -out ca.crt
  • 生成服务器证书(server.key, server.crt)
%> openssl genrsa -out server.key 2048

# 未使用CA签名的server.crt
%> openssl req -new -x509 -days 3650 \
     -subj "/C=CN/L=Shanghai/O=grpc-server/CN=server.grpc.me" \
     -key server.key -out server.crt
 
# 使用CA签名的server.crt
%> openssl req -new \
     -subj "/C=CN/L=Shanghai/O=grpc-server/CN=server.grpc.me" \
     -key server.key -out server.csr
%> openssl x509 -req -sha256 \
     -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650 \
     -in server.csr -out server.crt

使用Dnsmasq 实现 hosts 泛解析

$> sudo dnf install dnsmasq -y # 安装 Dnsmasq 
$> sudo cp /etc/dnsmasq.conf{,bak} # 先把配置文件备份一份
$> sudo vim /etc/dnsmasq.conf
# 严格按照 resolv-file 文件中的顺序从上到下进行 DNS 解析, 直到第一个成功解析成功为止
strict-order

# 监听的 IP 地址
listen-address=127.0.0.1

# 设置缓存大小
cache-size=10240

# 泛域名解析,访问任何 baidu.com 域名都会被解析到 6.6.6.6
address=/baidu.com/6.6.6.6

域名解析默认读取 /etc/hosts 文件到本地域名配置文件(不支持泛域名)。

DNS 配置默认读取 /etc/resolv.conf 上游 DNS 配置文件,如果读取不到 /etc/hosts 的地址解析,就会转发给 resolv.conf 进行解析地址。

如何在Fedora 33命令行模式下禁止睡眠

切换启动模式:

%> systemctl get-default # 获取当前启动模式
%> systemctl set-default multi-user.target # 默认命令行模式启动
%> systemctl set-default graphical.target # 默认图形模式启动

笔记本进入睡眠状态后,很多服务不能远程连接使用,例如 SSH 会连接不上,需要修改一下配置:

%> systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target # 禁止睡眠

%> systemctl unmask sleep.target suspend.target hibernate.target hybrid-sleep.target # 启用睡眠
 
%> vi /etc/systemd/logind.conf # 配置盖子(笔记本)
 
找到该行#HandleLidSwitch=suspend,将该行更改为以下所需的设置之一:
#关闭盖子时关闭计算机
HandleLidSwitch=poweroff
#在合上盖子时到休眠计算机
HandleLidSwitch=hibernate
#关闭盖子时暂停计算机
HandleLidSwitch=suspend
#不执行任何操作
HandleLidSwitch=ignore
 
%> systemctl restart systemd-logind # 保存文件,然后重新启动服务
%> service systemd-logind restart # 同上

部署v1.20版的Kubernetes集群

主机环境预设

本示例中的Kubernetes集群部署将基于以下环境进行。

  • OS: Ubuntu 20.04.1
  • Kubernetes:v1.20
  • Container Runtime: Docker CE 20.10.0

测试环境说明

测试使用的Kubernetes集群可由一个master主机及一个以上(建议至少两个)node主机组成,这些主机可以是物理服务器,也可以运行于vmware、virtualbox或kvm等虚拟化平台上的虚拟机,甚至是公有云上的VPS主机。

本测试环境将由master01、node01、node02和node03四个独立的主机组成,它们分别拥有4核心的CPU及4G的内存资源,操作系统环境均为仅小化部署的Ubuntu Server 20.04.1 LTS,启用了SSH服务,域名为magedu.com。此外,各主机需要预设的系统环境如下:

(1)借助于chronyd服务(程序包名称chrony)设定各节点时间精确同步;

(2)通过DNS完成各节点的主机名称解析;

(3)各节点禁用所有的Swap设备;

(4)各节点禁用默认配置的iptables防火墙服务;

注意:为了便于操作,后面将在各节点直接以系统管理员root用户进行操作。若用户使用了普通用户,建议将如下各命令以sudo方式运行。

Uber’s Real-Time Push Platform

Uber builds multi-sided marketplaces handling millions of trips every day across the globe. We strive to build real-time experiences for all our users.

The nature of real time marketplaces make them very lively. Over the course of a trip, there are multiple participants that can modify and view the state of an ongoing trip and need real-time updates. This creates the need to keep all active participants and apps synced with real-time information, whether it’s through pickup time, arrival time, and route lines on the screen, or nearby drivers when you open the app.

A key dimension of growth was feature explosion in critical user screens and the need for developers across the company to build real-time mobile features in a decentralized way on a shared app screen.

This article describes how we went from polling for refreshing the app to a gRPC-based bi-directional streaming protocol to build our app experience.

MacOS /usr/bin/目录下 Operation not permitted的解决

mac系统下的Rootless机制,让我们在root权限下也不能随心所欲的读写所有路径了,特殊情况下我们需要关闭Rootless时,可尝试如下操作:

  1. 重启按住 Command+R,进入恢复模式,打开Terminal;

  2. 键入命令 csrutil disable

  3. 再次重启,即可对 usr/bin 目录下文件进行修改;

  4. 如果要恢复保护机制,重新进入保护模式,输入 csrutil enable;

Rootless机制是对抗恶意程序的最后防线,除非特殊需要时我们才将其关闭,否则保持开启状态

Mac OS包管理软件brew和port介绍

Mac OS中主要有三种包管理工具:MacPorts,Homebrew,Fink。这里简介Homebrew和MacPorts的区别:

MacPorts
因为 Mac OS 源自 BSD,因此将 BSD 中的 Port 移植到 OS 成为 MacPorts 就一点不奇怪。MacPorts 会独立于 OS 自建一套仓库树,OS 的包执行目录为 /usr/local,而 MacPorts 的包执行目录为 /opt/local。MacPorts 尽量不影响系统现有程序,自然也就尽量少复用系统已有程序。MacPorts 安装包的过程是下载该程序的所有源文件及其依赖包,然后在本地进行 Build 生成最终的可执行文件。这样做的好处是在系统中存在一套独立的生态环境,从而不影响系统自身的生态环境,缺点就是浪费了系统自身的生态资源。

Homebrew
在 Lion 之后兴起的包管理工具,工作方式与 MacPorts 类似,下载源代码然后本地 Build。不同之处在于 Homebrew 采取与 MacPorts 截然相反的态度,对系统资源是最大程度的利用,因此可以说 Homebrew 是直接对现有系统生态环境进行修改,所有包也是直接安装到现有的生态环境中,这样做的好处是节约了系统资源,但缺点是每一次操作都是直接对系统进行修改,严重依赖和影响现有系统。

使用 MacPorts 和 Homebrew 都需要预装 XCode Command Line Tools,即意味着还需要提前预装 XCode。(根据官方文档来看,Fink 安装比较新的工具包时,因为提前编译完成所以无需依赖 XCode,但对于一些不是二进制的包,如果需要本地编译,还是需要依赖 XCode。换而言之,如果想在 OS 中编译源码,都需要 XCode 提供支持)

Kotlin: 几种设计模式

创建型模式

原始模型

interface Computer {
	val cpu: String
}

class PC(override val cpu: String = "Core"): Computer
class Server(override val cpu: String = "Xeon"): Computer

enum class ComputerType {
	PC, Server
}

class ComputerFactory {
	fun produce(type: ComputerType): Computer {
		return when(type) {
			ComputerType.PC -> PC()
			ComputerType.Server -> Server()
		}
	}
}

>>> val comp = ComputerFactory().produce(ComputerType.PC)
>>> println(comp.cpu)
Core

Tg: Serialized binary TL-schema in vkext format(*.tlo)

---types---
/////
//
// Serialized binary TL-schema in vkext format
//
/////

tls.schema_v2 version:int date:int types_num:# types:types_num*[tls.Type] constructor_num:# constructors:constructor_num*[tls.Combinator] functions_num:# functions:functions_num*[tls.Combinator] = tls.Schema;

tls.type name:int id:string constructors_num:int flags:int arity:int params_type:long = tls.Type;
tls.combinator name:int id:string type_name:int left:tls.CombinatorLeft right:tls.CombinatorRight = tls.Combinator;
tls.combinatorLeftBuiltin = tls.CombinatorLeft;
tls.combinatorLeft args_num:# args:args_num*[tls.Arg] = tls.CombinatorLeft;

tls.combinatorRight value:tls.TypeExpr = tls.CombinatorRight;

tls.arg id:string flags:# var_num:flags.1?int exist_var_num:flags.2?int exist_var_bit:flags.2?int type:tls.TypeExpr = tls.Arg;

tls.exprType _:tls.TypeExpr = tls.Expr;
tls.exprNat _:tls.NatExpr = tls.Expr;

tls.natConst value:int = tls.NatExpr;
tls.natVar dif:int var_num:int = tls.NatExpr;

tls.typeVar var_num:int flags:int = tls.TypeExpr;
tls.array multiplicity:tls.NatExpr args_num:# args:args_num*[tls.Arg] = tls.TypeExpr;
tls.typeExpr name:int flags:int children_num:# children:children_num*[tls.Expr] = tls.TypeExpr;
---functions---