0%

内建变量

  • bool
  • string
  • (u)int[8/16/32/64],uintptr
  • byte
  • rune go的char类型,长度32位
  • float[32/64]
  • complex[64/128] 复数类型

变量定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 1 单个定义
var a int
var b string

// 2 多个定义
var a, b int = 3, 4

// 3 类型判断 省略类型 TypeDeduction
var a, b , = 3, "4", true

// 4 省略var
a,b = 1, 2

// 5 函数外定义 包内部定义
var(
aa = 1
bb = "bb"
)

常量与枚举

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
30
31
32
// 1 单个定义
const filename = "xxx"

// 2 多个定义
const a, b = 1, 3

// 3 定义多个
const (
...
)

// 4 枚举类型 iota表示值自增
func enums() {
const(
cpp = iota
- //可跳过一个值
java
python
golang
javascript
)
}

// 5 枚举类型 iota计算
const(
b = 1 << (10 * iota)
kb
mb
gb
tb
pg
)
Read more »

Basic Commands

命令 描述
create/apply 从文件或stdin创建资源
expose 为deployment、pod创建service
run 在集群中运行指定的镜像
set 在对象上设置一个specific
get 最基本的查询命令 可以get一切资源信息
explain 查看资源定义,如 kubectl explain replicaset
edit 使用系统编辑器编辑资源 kubectl edit deploy/foo
delete 删除指定资源,支持文件名、资源名、label selector。kubectl delete po -l foo=bar

Deploy Commands

命令 描述
rollout Deployment、DaemonSet的升级过程管理 查看状态、操作历史、暂停升级、恢复升级、回滚
rolling-update 客户端滚动升级,仅限ReplicationController
scale 修改Deployment、ReplicaSet、ReplicationController,Job的实例数
autoscale 为Deployment、ReplicaSet、ReplicationController配置自动伸缩规则,依赖heapster和hpa
Read more »

核心功能

  • 服务发现与负载均衡
  • 容器自动装箱
  • 存储编排
  • 自动容器护肤
  • 自动发布与回滚
  • 配置与密文管理
  • 批量执行
  • 水平伸缩

Pod

  • 一组功能相关的Container的封装
  • 共享存储和Network Namespace
  • 容易走失,需要Workload和Service的呵护

Pod调度过程

Workloads

含Deployment、StatefulSet、DaemonSet、Job、Cronjob

Service

  • Pos 防失联
  • 给一组Pod设置反向代理
Read more »

Istio策略和遥测的原理

Istio通过专门的服务端组件,提供一种扩展机制来手机服务运行的遥测数据和服务间的访问,执行一定的策略。

应用场景

采集数据、存储数据、检索数据

通过Sidecar Inbound和Outbound都想Mixer上报数据。Mixer提供对应APM的Adapter。解耦Sidecar和APM的通讯,由Mixer来集中对接。

工作原理

每个插件都是一个Adapter,Mixer通过它们与不同的基础设施后端连接。提供日志、监控、配额、ACL检查等功能。

因为每个基础设施后端都有不同的接口和操作,所以需要自定义代码进行处理,这就是Mixer的Adapter机制。

Mixer通过Protobuf格式定义Adapter的配置。

属性

Envoy上报的数据istio中称为属性 attribute。属性是一小块数据,描述服务请求或者服务运行环境的信息。

属性列表: https://istio.io/docs/reference/config/policy-and-telemetry/attribute-vocabulary/

属性表达式

属性表达式: https://istio.io/docs/reference/config/policy-and-telemetry/expression-language/

Mixer的匹配模型

istio主要通过handler、instance、rule这三个资源对象来描述Adapter的配置。

业务处理 Handler

Handler来描述Adapters及其配置。Mixer每个Adapter都需要一些配置才能运行。不同额Adapter有不同的配置,比如服务后端信息之类的。

如果Adapter看做是一个模板的定义的话,Handler就是这个模板的实现。

Read more »

安装及启动

1
2
3
4
5
curl -Lo minikube https://github.com/kubernetes/minikube/releases/download/v1.5.2/minikube-linux-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/

minikube start --image-mirror-country cn \
--iso-url=https://kubernetes.oss-cn-hangzhou.aliyuncs.com/minikube/iso/minikube-v1.5.1.iso \
--registry-mirror=https://kucfkskm.mirror.aliyuncs.com

Install kubectl on Linux

1
2
3
curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.17.0/bin/linux/amd64/kubectl &&\
chmod +x ./kubectl &&\
sudo mv ./kubectl /usr/local/bin/kubectl

参考资料

常用到,记录一下

1
2
3
4
wget https://www.php.net/distributions/php-7.2.25.tar.gz
tar zxvf php-7.2.25.tar.gz
cd php-7.2.25/
./configure --help
1
2
3
4
5
6
7
8
9
10
11
yum install -y systemd-devel libpng-devel openjpeg-devel libxml2-devel curl-devel libicu-devel libjpeg libpng freetype libjpeg-devel libpng-devel freetype-devel
./configure --prefix=/usr/local/php7 --with-fpm-user=www --with-fpm-group=www --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd --enable-fpm --with-openssl --enable-exif --disable-fileinfo --enable-ftp --with-gd --enable-mbstring --enable-zip --with-curl --enable-bcmath --with-fpm-systemd --enable-sockets --with-mhash --with-zlib --with-gettext --with-png-dir=/usr/lib --with-jpeg-dir=/usr/lib --enable-pcntl --enable-opcache --enable-intl --enable-session
make
make install
---
ln -s /usr/local/php7/etc/ /etc/php7
cp php.ini-production /usr/local/php7/etc/php.ini
加入 zend_extension=/usr/local/php7/lib/php/extensions/no-debug-non-zts-20170718/opcache.so
cp sapi/fpm/php-fpm.service /usr/lib/systemd/system/php-fpm.service
cp /usr/local/php7/etc/php-fpm.conf.default /usr/local/php7/etc/php-fpm.conf
cp /usr/local/php7/etc/php-fpm.d/www.conf.default /usr/local/php7/etc/php-fpm.d/www.conf
Read more »

Istio流量治理原理

istio流量治理主要有以下流程

控制面:

  1. 管理员通过命令行或者api创建流量规则
  2. Pilot将流量规则转换为Envoy的标准格式
  3. Pilot将规则下发给Envoy

数据面:

  1. Envoy拦截Pod上本地容器Inbound和Outbound的流量
  2. 在流量经过Envoy时,执行对应的流量规则,进行流量治理

负载均衡

主要用户服务间访问。通过它可以在多个服务实例找到一个合适的后端把请求转发过去。

Pilot维护服务发现数据,下发给Envoy,Envoy根据负载均衡策略选择一个实例转发请求。

服务熔断

istio的熔断控制无需侵入代码,有别与hystrix。

常见的熔断器状态流转

序号 初始状态 条件 迁移状态
1 熔断关闭 请求成功 熔断关闭
2 熔断关闭 请求失败,调用失败次数自增,不超过阀值 熔断关闭
3 熔断关闭 请求失败,调用失败次数自增,超过阀值 熔断开启
4 熔断开启 熔断器维护计时器,计时未到 熔断开启
5 熔断开启 熔断器维护计时器,计时到了 熔断半开启
6 熔断半开启 访问成功 熔断关闭
7 熔断半开启 访问失败 熔断开启

故障注入

有些故障是不会经常触发的,以前模拟故障通常需要修改代码来模拟。而Istio也提供了这个能力。

灰度发布

  1. 蓝绿发布
    类似热发布。先部署新版本,等新版可用后,全流量切换过去。
  2. AB测试
    部署对等的两个版本A和B,分流一部分去a,一部分去b,然后根据运营收集数据,根据反馈选择使用哪个版本。
  3. 金丝雀发布/灰度发布

你叫像AB测试发布,先让小部分用户尝试新版本。观察一段时间后决定使用哪个版本。

Read more »

Istio工作机制

Istio主要架构分为控制面和数据面两部分。

数据面: Envoy
控制面: PilotMixerCitadel

工作机制

  1. 自动注入: k8s中,当有pod创建时候,调用sidecar-injector服务,修改程序描述信息,注入sidecar。主要就是envoy。
  2. 流量拦截:在pod中用iptables拦截容器的流量
  3. 服务发现: Envoy调用Pilot的服务发现接口获取目标服务的实例列表
  4. 负载均衡: 服务发起方的Envoy根据负载均衡策略选择服务实例
  5. 流量治理: Envoy从Pilot获取流量规则,将流量转发到对应的服务上。
  6. 访问安全: Envoy之间的通讯进行双向认证和通道加密,并基于服务的身份授权管理。其中证书和密钥主要由Citadel组件维护
  7. 服务遥测: 服务通讯期间,双方的Envoy都会向Mixer组件上报访问数据。
  8. 策略执行: 可以用Mixer控制服务间的访问
  9. 外部访问: 在网格的入口有一个Envoy扮演入口网关的角色。

服务模型

由istio服务、服务版本、服务实例几个对象构成

服务模型约束

  • 端口命名: name: <protocol>[-<suffix>],协议支持常用的服务协议,如mysql、redis,如无指定,默认为tcp协议
  • 服务关联: pod需要关联到服务
  • deployment使用app和version标签: 区分版本

istio服务

k8s只要满足上文提到的服务模型约束,就可以转为 istio 的服务并配置规则进行流量治理。如最小的k8s模型加上端口命名

k8s主体是 workload,istio 的对象主体是 service,没有访问方式的workload 不是 istio 治理对象。Kubernetes 的 Service 定义 就是 Istio 服务 的 元 数据。

istio服务版本

通过deployment的app: service-name 来关联服务。 通过version: v<version> 标签来区分服务不同版本。 可以根据这个实现灰度发布等功能。

istio服务实例

Istio 的 ServiceInstance 主要包括 Endpoint、 Service、 Labels、 AvailabilityZone 和 ServiceAccount 等属性, Endpoint 是其中最主要 的属性,表示这个实例对应的网络后端( ip: port), Service 表示这个服务 实例归属的服务。

Read more »

需求

主要用于运营部使用h5图片,又想自定义标题. 但是时不时找我很烦,就搞了这个东西给她用。nodejs还挺好玩的。

使用说明

原理,使用表单提交数据. 将数据用ejs渲染到模板上,然后保存成html.

安全码:是防止恶意提交做的一个小验证,写死在 routes/index.js:13 xxx123

运行 npm run start 默认端口是4001

pm2运行 pm2 start npm --name "h5-generator" -- run start
删除任务 pm2 delete h5-generator

生成的文件目录在 ./public/html

由于用在www.xxx.com

所以我nginx配置如下

1
2
3
4
5
6
7
8
9
10
11
12
13
   # 访问程序
location /generate/ {
proxy_pass http://127.0.0.1:4001/;
proxy_read_timeout 300s;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# 访问生成的html文件
location /h5 {
  # public/html 绝对路径
alias /data/wwwroot/h5_generator/public/html;
}

h5生成器页面:  https://www.xxx.com/generate/h5

生成的文件访问地址: https://www.xxx.com/h5/生成文件名.html

主要代码

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
30
31
32
33
34
35
36
37
38
var express = require('express');
const process = require('process');
const ejs = require('ejs')
const fs = require('fs');
var router = express.Router();

/* GET home page. */
router.get('/h5', function(req, res, next) {
res.render('index', { title: 'H5 生成' });
});

router.post('/generate', function (req, res) {
if(req.body.password==='xxx123') {
ejs.renderFile('./templates/h5.ejs',req.body,{},function (err, str) {
if (err) {
console.log(err)
res.send('读取模板文件出错啦.')
} else {
const date = new Date();
const month = date.getMonth() + 1
const filename = ''+ date.getFullYear() + month + date.getDate() + req.body.filename.replace(/(^\s*)|(\s*$)/g, "")+'.html';
console.log('filename', filename)
fs.writeFile('./public/html/'+filename, str, (err) => {
if (err) {
res.send(err)
}else{
res.send('http://www.xxxx.com/h5/'+filename);
}
});

}
})
} else {
res.send('操作码错误')
}
});

module.exports = router;
Read more »

项目概要

  • 项目定义

项目是为创造独特产品、服务或者成果而进行的临时性工作。

  • 项目的特点

变革性、临时性、跨职能性、不确定性

  • 项目管理的五大要素

时间、成本、范围、质量、风险

  • 项目管理的五大过程

启动、规划、执行、监控、收尾

  • 项目的理论体系

PMBOK、Prince2

Read more »

红帽系源是默认用mariadb的,而且mariadb也很优秀,但是我们开发是基于MySQL5.7上做的开发,基本10.2起,应该对MySQL5.7所有的特性是完整支持的.

但是为了稳妥,还是决定给客户安装一样的版本.

在官网找文档的时候,发现藏得有点深,所以还是打算记录下.

安装

完整的命令大致如下

1
2
3
4
shell> yum install -y https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
shell> yum repolist all | grep mysql
shell> sudo yum-config-manager --disable mysql80-community
shell> sudo yum-config-manager --enable mysql57-community

当看到mysql源是57(自己想要的版本的时候就可以直接安装了)

1
2
3
4
5
6
shell> yum repolist enabled | grep mysql
mysql-connectors-community/x86_64 MySQL Connectors Community 118
mysql-tools-community/x86_64 MySQL Tools Community 95
mysql57-community/x86_64 MySQL 5.7 Community Server 364

shell> yum install mysql-community-server

Read more »

下载地址

https://www.charlesproxy.com/latest-release/download.do

example:

wget https://www.charlesproxy.com/assets/release/4.2.8/charles-proxy-4.2.8_amd64.tar.gz

破解文件

破解文件生成: https://www.zzzmode.com/mytools/charles/

tar zxvf charles-proxy-4.2.8_amd64.tar.gz

把下载的破解文件覆盖到 charles/lib 目录即可

添加charles ca证书 抓取https数据

  1. 访问: chls.pro/ssl 下载证书

  2. 放置证书
    创建个目录放证书 sudo mkdir /usr/share/ca-certificates/charles
    sudo mv ~/charles-ssl-proxying-certificate.pem /usr/share/ca-certificates/charles

  3. 刷新证书配置

Read more »

本地是在虚拟机中建立的k8s环境,安装好后,因为没有负载均衡器,所externalip一直处于pending.官网解决方案是使用nodeport转发.

但是,直接edit svc填写externalip为虚拟机ip即可正常使用了.

1
2
3
4
# kubectl edit svc istio-ingressgateway -n istio-system
spec:
externalIPs:
- xxx.xxx.xxx.xxx
Read more »

之前跨域处理的header都是后端返回的.昨天改回nginx来添加这个header,感觉这样写比较好用清晰,所以记录一下.

注意在allow headers添加上自己额外增加的header就好了,比如我们header添加了token,所以这里也加了.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
set $origin '*';
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' $origin;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,token';
add_header 'Content-Length' 0;
return 204;
}

if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' $origin;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,token';
}

if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' $origin;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,token';
}
Read more »

开始

什么是 GraphQL?

GraghQL的介绍,概览和概念,参考 官方介绍

让我们构建一个基本的GraphQL schema.

依赖

  • Python(2.7, 3.4, 3.5, 3.6, pypy)
  • Graphene (2.0)

项目安装

1
pip install "graphene>=2.0"

创建一个基础的Schema

一个描述你数据模型的GraphQL Schema,和提供GraphQL 服务,关联对应的解析方法,该方法知道怎样获取对应的数据.

我们将创建一个非常简单的schema,一个Query,只有一个field:hello和输入名字.当我们查询它,它应当返回`”Hello {argument}”.

1
2
3
4
5
6
7
8
9
import graphene

class Query(graphene.ObjectType):
hello = graphene.String(argument=graphene.String(default_value="stranger"))

def resolve_hello(self, info, argument):
return 'Hello ' + argument

schema = graphene.Schema(query=Query)

查询

然后我们开始查询我们的schema:

1
2
3
4
5
6
result = schema.execute('{ hello }')
print(result.data['hello']) # "Hello stranger"

# or passing the argument in the query
result = schema.execute('{ hello (argument: "graph") }')
print(result.data['hello']) # "Hello graph"
Read more »

最近consul节点被意外终止后,重新运行.发现该节点下的服务均无法注册上去.

看日志,发现类似的错误

1
rpc error making call: failed inserting node: Error while renaming Node ID: "xxxxx": Node name node2 is reserved by node xxxxxx-xxxxx-384e-0bf4-xxxxx with name node2

日志里两个node id是不一样的. 估计是重启后,生成了新的node id.这和挂掉之前,存在consul server中的 node2的id不一致,导致冲突.

解决

上面例子中,我是在节点2执行了一个 consul leave的动作就好了.

1
docker exec consul consul leave

如果不行,就 离开集群 -> 重启consul -> 加入集群

另外看到其它应该可行的方法,但是我没有尝试.

以上问题,主要是因为生成了新的node id 导致的node id冲突. 那不让它生成不就好了.

启动时加入-disable-host-node-id

或者指定node id -node-id=$(uuidgen | awk ‘{print tolower($0)}‘) node id必须是guid格式

Read more »

1. 注解方式

如: @app.route('/')

1
2
3
4
5
6
7
8
9
10
11
12
# -*- coding: utf-8 -*-

from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():
return 'index.'


app.run(debug=True)

@app.route('/')还可以附带options.如限定特定的method. @app.route(rule='/',methods=['GET','POST'])

2. app.add_url_rule('/',view_func=index)

实际上注解也是调用了这个接口,来注册的.只不过用了闭包形式来封装注册过程显得更为简洁.

1
2
3
4
5
6
7
8
9
10
11
12
13
# -*- coding: utf-8 -*-

from flask import Flask

app = Flask(__name__)


def index():
return 'index.'

app.add_url_rule(rule='/', view_func=index)

app.run(debug=True)
Read more »

最近经常需要装nodejs,在发现有这个方法后,毅然抛弃了源码安装,舒服.

1
2
3
4
5
curl --silent --location https://rpm.nodesource.com/setup_8.x | sudo bash -
yum install -y nodejs
yum install -y gcc-c++ make
curl -sL https://dl.yarnpkg.com/rpm/yarn.repo | sudo tee /etc/yum.repos.d/yarn.repo
yum install yarn

参考资料

Read more »

什么是容器

  • 资源视图隔离 - namespace
  • 控制资源使用率 - cgroup
  • 独立的文件系统 - chroot

容器是一个视图隔离、资源可限制、独立文件系统的进程集合。

什么是镜像

运行容器所需要的所有文件集合 - 容器镜像

Dockerfile - 描述镜像构建步骤

构建步骤所产生出文件系统的变化 - changeset

容器的生命周期

单进程模型

  1. init进程生命周期 - 容器生命周期
  2. 运行期间可运行exec执行运维操作

数据持久化

  1. 独立于容器的生命周期
  2. 数据卷 - docker volume vs bind

容器项目架构

moby 容器引擎架构

  • containerd
  1. 容器运行时管理引擎,独立于moby daemon
  2. containerd-shim 管理容器生命周期 可以被containerd动态接管
  • 容器运行时
  1. 容器虚拟化技术方案
  2. runC kata gVisor
Read more »