lua package 面向对象开发

lua 作为一门简单的语言,在变量是只有 table 和非 table 的区别。

基本

1
2
3
4
5
6
local _M = {} 
function _M:foo()
...
end

return _M

在 lua 中 _M:foo() 就是 _M.foo(self) 。在使用时和个人习惯有关。这里我希望能够严格的区分库和对象.当函数为静态方法时,比如一些utils函数,使用点号(.)。当函数需要面向对象时,使用冒号(:)。

阅读更多

go-singlefilght

singleflight

1
2
golang.org/x/sync/singleflight

singleflight 是 go 提供的一个扩展并发原语,主要是用来合并请求来降低服务压力。

code

1
https://cs.opensource.google/go/x/sync/+/036812b2:singleflight/singleflight.go

原理

实现了一个 Group 的 struct

1
2
3
4
type Group struct {
mu sync.Mutex // protects m
m map[string]*call // lazily initialized
}
阅读更多

docker build alpine dns error

使用 alpine 构建 Ddockerfile ,导致 docker 打包失败,错误如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
fetch https://mirrors.aliyun.com/alpine/v3.13/main/x86_64/APKINDEX.tar.gz
fetch https://mirrors.aliyun.com/alpine/v3.13/community/x86_64/APKINDEX.tar.gz
v3.13.4-69-g5bcff43ec5 [https://mirrors.aliyun.com/alpine/v3.13/main]
v3.13.4-66-g32aee0eba0 [https://mirrors.aliyun.com/alpine/v3.13/community]
OK: 13892 distinct packages available
fetch https://mirrors.aliyun.com/alpine/v3.13/main/x86_64/APKINDEX.tar.gz
WARNING: Ignoring https://mirrors.aliyun.com/alpine/v3.13/main: DNS lookup error
fetch https://mirrors.aliyun.com/alpine/v3.13/community/x86_64/APKINDEX.tar.gz
WARNING: Ignoring https://mirrors.aliyun.com/alpine/v3.13/community: DNS lookup error
ERROR: unable to select packages:
bash (no such package):
required by: world[bash]
curl (no such package):
required by: world[curl]
ERROR: Service 'microservice-users-rpc' failed to build : The command '/bin/sh -c apk update && apk add --no-cache curl bash' returned a non-zero code: 2
make: *** [docker-compose-up] Error 1
阅读更多

Docker & K8S 实践

使用 marp 制作的用于内部分享的 docker && k8s 的文档。


marp: true
theme: uncover
paginate: false
header: ‘NXDev

Docker & K8S 实践

纳星科技 张巍


Docker

是新技术吗?
解决了什么问题 ?


是新技术吗?

linux 的Namespaces + Cgroup
配合一种被称为 Union file system 的文件系统
最后打成一个包。


解决了什么问题?

  1. 对开发来说,统一了开发的环境。开发环境不一致的问题不再是问题。
  2. 对运维来说,上线只需要一条命令。 把所有的代码装进盒子。

Docs : https://docs.docker.com

安装

架构

Docker Run Gin


Docker 如何安装

https://docs.docker.com/get-docker/

Linux

1
2
$ curl -fsSL https://get.docker.com -o get-docker.sh
$ sudo sh get-docker.sh

先看看 怎么用的

gin-hello
mysql


Docker 架构

bg right:60% fit


镜像 (Image)
容器 (Container)
仓库 (Repository)


镜像(Image)

相当于是一个 root 文件系统。比如官方镜像 ubuntu:16.04 就包含了完整的一套 Ubuntu16.04 最小系统的 root 文件系统。

1
2
3
4
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql 5.7 9cfcce23593a 5 weeks ago 448MB
redis 3.2-alpine 6e94a98d3442 21 months ago 22.9MB

容器(Container)

镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。

1
2
3
4
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3548302772b1 redis:3.2-alpine "docker-entrypoint.s…" 3 weeks ago Up 3 weeks 0.0.0.0:6379->6379/tcp redis_redis_1
37259a661f27 xxiu/mysql "docker-entrypoint.s…" 3 weeks ago Up 3 weeks 0.0.0.0:3306->3306/tcp, 33060/tcp mysql_mysql_1

仓库(Repository)

仓库可看成一个代码控制中心,用来保存镜像。

  • 自己搭: Harbor
  • 阿里云:

核心技术

bg right:60% fit

Namespaces

Cgroup

Union file systems

Container format


Namespaces & Cgroup

linux 内核做资源隔离的两个概念。

所以 docker 和虚拟机的区别在于:

  • 虚拟机虚拟了整套的操作系统,
  • docker 只是在linux 内核上做了资源隔离。

Namespaces

资源隔离

bg right:68% fit


cgroup

Cgroup:控制程序对资源的占用。

  • 对进程组使用的资源总额进行限制;

  • 通过分配CPU时间片数量/磁盘IO/带宽大小,实际上就是相当于控制子进程运行的优先级。

  • 统计系统资源使用量,比如CPU使用时间,内存使用量等

  • 进程控制,恢复执行进程


Union file systems

img

  • boots:
    boot loader + kernel ,用户不可修改 (共享主机的内核)

  • root file system : 包括典型的 linux 目录结构:
    /dev /proc /bin /etc /lib /usr /tmp 等配置文件,二进制文件,库文件


AUFS (Union FS) : 支持将不同的目录挂载到虚拟目录下。

img


bg fit

bg fit


Docker Run Gin

1
2
3
4
5
6
7
8
9
func main() {
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
})
r.Run(":8080")
}
1
go build . -o main

Dockerfile

1
2
3
4
5
FROM scratch
WORKDIR /root/
COPY main /root/main
EXPOSE 8080
CMD ["/root/main"]
1
2
3
docker build  -t ginhello .
docker ps |grep ginhello
docker run -it ginhello

1
2
3
语法
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

  • OPTIONS:
    开放的端口/挂载的文件/传入的变量…
  • IMAGE:
    正常的镜像名:
    registry.cn-beijing.aliyuncs.com/nxops/gin-hello:v0.0.2
  • COMMAND && ARG…

例如:

1
docker run -itd --name mysql-test -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql

运行 docker 的命令又长 参数又多,怎么办?


docker-compose

还是来用一个文件来描述刚才我们的 run 命令

1
2
3
4
5
6
7
8
9
# docker-compose.yml
version: '3'
services:
gin-hello:
image: registry.cn-beijing.aliyuncs.com/nxops/gin-hello:v0.0.2
build: .
restart: always
ports:
- 8080:8080

mysql

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
version: '3'

services:
mysql:
image: mysql
build: .
volumes:
- ./data:/var/lib/mysql
- ./conf.d/mysql.cnf:/etc/mysql/conf.d/mysql.cnf
environment:
- MYSQL_ROOT_PASSWORD=pprt123
- MYSQL_USER=pprt
- MYSQL_PASSWORD=pprt123
ports:
- 3306:3306
command: --lower-case-table-names=1 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
restart: always

接下来命令变得简单了
gin-hello

1
2
3
4
docker-compose build gin-hello
docker-compose push|pull gin-hello
docker-compose run gin-hello
docker-compose exec gin-hello bash

mysql

1
docker-compose run mysql 

K8S

K8s 是什么 ?

容器的调度和管理。


minikube

1
2
3
4
5
6
7
8
9
10
11
# 安装 kubectl
brew install kubectl

# 安装 minikube
# https://github.com/AliyunContainerService/minikube
# https://developer.aliyun.com/article/221687

curl -Lo minikube https://kubernetes.oss-cn-hangzhou.aliyuncs.com/minikube/releases/v1.12.1/minikube-darwin-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/

## 选择环境
kubectl config use-context minikube

example :gin-hello


架构

bg fit right:80%


  • etcd保存了整个集群的状态;
  • apiserver提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制;
  • controller manager负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;
  • scheduler负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上;
  • kubelet负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理;
  • Container runtime负责镜像管理以及Pod和容器的真正运行(CRI);
  • kube-proxy负责为Service提供cluster内部的服务发现和负载均衡;

  • kube-dns负责为整个集群提供DNS服务
  • Ingress Controller为服务提供外网入口
  • Heapster提供资源监控
  • Dashboard提供GUI
  • Federation提供跨可用区的集群
  • Fluentd-elasticsearch提供集群日志采集、存储与查询

整体

bg fit right:75%


master

bg fit right:75%


Node

bg fit right:75%


kubernetes 它都管理了什么

资源


一切都是资源,根据需要去申请。
网络,存储,cpu,内存
有状态服务,无状态服务,任务,定时任务,配置
……

所有的资源都靠一行命令:

1
kubectl apply -f  <filename.yaml>

控制器

bg right:70% fit

应用控制

  • Deployment
  • DaemonSet
  • StatefulSet
  • Job/CronJob

应用配置

  • ConfigMap
  • Secret

访问方式

  • Service
  • Ingress

service

https://kubernetes.io/zh/docs/concepts/services-networking/service/#loadbalancer
service 的四种网络

  • ClusterIP 集群内部暴露ip,(默认)
  • NodeIP 通过每个 Node 上的 ip 和NodePort 暴露服务,NodePort 会路由到 ClusterIP
  • LoadBalancer 使用云提供商的均衡负载服务。 向外暴露服务
  • ExternalName 通过返回 CNAME 和它的值。

ingress

1
2
3
4
5
  internet
|
[ Ingress ]
--|-----|--
[ Services ]

ingress 被称为server 的 server。
被用来作为网络的七层代理
其实它就是做 Nginx 的事情


Ingress Controllers

在使用七层代理时,我们需要对代理做一些配置
比如 nginx 的 upstream proxy_pass

Ingress Controllers 通过 watch ingress,将它转化为数据平面的配置。

1
2
3
4
5
  internet
|
[ Ingress ] <-- [Ingress Controllers ] kubuctl
--|-----|-- | |
[ Services ] [etcd]<----------------

Ingress 选型

  1. Nginx Ingress
  2. Kong Ingress
  3. APISIX Ingress
  4. Traefik
  5. Haproxy

Kong

Kong = Openresty + config
Openresty = Nginx + lua


END

golang sync

##Goroutine 内存占用

下面是一个创建 goroutine 什么也不干,对内存的占用打印。说明创建 goroutine 的成本非常低。

1
2
3
4
5
6
7
num:1  mem: 0.062MB average:64.000kb 
num:10 mem: 0.000MB average:0.000kb
num:100 mem: 0.000MB average:0.000kb
num:1000 mem: 0.250MB average:0.256kb
num:10000 mem: 1.373MB average:0.141kb
num:100000 mem: 265.852MB average:2.722kb
num:1000000 mem: 2462.125MB average:2.521kb

以下是创建代码:

阅读更多

tcp连接数

Tcp 连接中,Server 监听固定端口,Client 发起主动连接。 经过三次握手后建立 Tcp 连接。

Client

client 每次请求,如果不固定端口,系统会选用一个空闲端口。该端口是独占,不能和其他 Tcp 连接共享。本地端口最大数为 65536 ,0 有特殊含义(预留,系统指定动态生成的端口),其他的全作为 client 情况下 ,最大连接数为65535 。 除去系统服务使用的端口,能够使用的会比这个少一些,1024 一下的端口通常为保留端口。

阅读更多

jenkins 配置说明

这是给团队写的 jenkins 会出现问题的说明,简单的描述了 jenkins 使用中会出现的问题,以及应对方法。当然最好的应对方法是没有问题。

jenkins 是什么

jenkins 自动化的命令运行引擎,pipeline (流水线) 是按照既定的逻辑来执行 jenkinsfile 中的代码。

也就是说它只是一个流程执行引擎,所有的命令都需要依赖其它软件包。 比如 npm ,maven, ansiable 等等。当使用 docker 来启动 jenkins 时,需要在 dockerfile 里面加上打包需要的依赖。

阅读更多

生成分布式id

分布式系统中经常需要生成全局唯一 id ,要求:

  1. 全局唯一: 不能出现重复ID

  2. 高可用: 作为基础系统,被许多关键系统调用,一旦宕机,影响严重

阅读更多

docker_sysctl

Sysctl 用于配置运行时的内核参数,正常情况下修改 /etc/sysctl.conf . 然后执行 sysctl -p 就能够设置成功。

当使用 Docker 启动服务时,使用 sysctl -p 来配置 docker 的参数时会出现问题。比如

1
2
sysctl: cannot stat /proc/sys/net/core/rmem_max: No such file or directory
sysctl: cannot stat /proc/sys/net/core/wmem_max: No such file or directory
阅读更多