LOFTER for ipad —— 让兴趣,更有趣

点击下载 关闭

docker

3218浏览    181参与
IT职业规划师|徐老师

java培训一对一在线辅导Java编程答疑教学就业项目指导

java讲解,spring框架,mysql,辅导web技能提升 dubbo  redis 等  职业规划指导

提升一个技能让你干掉上千竞争者!

java培训一对一在线辅导Java编程答疑教学就业项目指导

java讲解,spring框架,mysql,辅导web技能提升 dubbo  redis 等  职业规划指导

提升一个技能让你干掉上千竞争者!

yangli-1128

docker 安装 canal 笔记

1.在centos8中使用podman 安装canal,,结果失败,提示【su :incorrect password】,找了各种办法,都失败。最后只使用 centos6.10的镜像,执行 su ,也提示【su :incorrect password】。最终方式使用podman


2.在centos8中安装docker,安装方法【https://docs.docker.com/engine/install/centos/】


3.下载canal镜像

docker pull canal/canal-server

l

1.在centos8中使用podman 安装canal,,结果失败,提示【su :incorrect password】,找了各种办法,都失败。最后只使用 centos6.10的镜像,执行 su ,也提示【su :incorrect password】。最终方式使用podman


2.在centos8中安装docker,安装方法【https://docs.docker.com/engine/install/centos/】


3.下载canal镜像

docker pull canal/canal-server

l

Tops博客

Docker笔记

开始



安装

sudo apt-get update
sudo apt-get install docker.io

查看Docker信息、版本

docker info
docker version

更换国内源

curl -sSL https://get.daocloud.io/daotools/set_mirror.sh sh -s http://187b68ff.m.daocloud.io

测试与Docker Hub的连接

docker run hello-world
结果:
Hello from Docker …… 说明成功...

开始



安装

sudo apt-get update
sudo apt-get install docker.io


查看Docker信息、版本

docker info
docker version


更换国内源

curl -sSL https://get.daocloud.io/daotools/set_mirror.sh sh -s http://187b68ff.m.daocloud.io


测试与Docker Hub的连接

docker run hello-world
结果:
Hello from Docker …… 说明成功


登陆退出

docker login -u topzyh -p 密码
docker logout


DockerUI安装,安装完成后访问 IP:9000

docker run -d -p 9000:9000 --privileged -v /var/run/docker.sock:/var/run/docker.sock uifd/ui-for-docker


镜像



搜索镜像

docker search Ubuntu



检查 official 为 [OK] ,表示官方镜像


下载镜像

docker pull ubuntu:16.10
docker pull learn/tutorial


上传镜像到docker平台(需要登陆docker.io)

docker push <镜像名或ID>[:TAG]


查看所有镜像

docker images


将镜像保存成tar文件

docker save -o my_ubuntu_v3.tar <镜像名或ID>


从tar文件中创建镜像

docker import my_ubuntu_v3.tar <镜像名或ID>


删除镜像

docker rmi <镜像名或ID>
docker rmi $(docker images grep none awk '{print $3}' sort -r) //删除所有镜像


容器生命周期



通过镜像创建一个新的容器并进入

docker run -it ubuntu



  • -d: 后台运行容器,并返回容器ID;

  • -it: 会打开一个 shell与容器交互, exit 从容器中退出

  • --name="nginx-lb": 为容器指定一个名称;

  • --dns 8.8.8.8: 指定容器使用的DNS服务器,默认和宿主一致;

  • --dns-search example.com: 指定容器DNS搜索域名,默认和宿主一致;

  • -h "mars": 指定容器的hostname;

  • -e username="ritchie": 设置环境变量;

  • --env-file=[]: 从指定文件读入环境变量;

  • --cpuset="0-2" or --cpuset="0,1,2": 绑定容器到指定CPU运行;

  • -m :设置容器使用内存最大值;

  • --net="bridge": 指定容器的网络连接类型,支持 bridge/host/none/container: 四种类型;

  • --link=[]: 添加链接到另一个容器;

  • --expose=[]: 开放一个端口或一组端口;



间接运行容器

docker run learn/tutorial echo "hello word" //hello world
docker run learn/tutorial apt-get install -y ping //安装新程序
docker run lean/ping ping www.google.com //运行新容器


创建一个新的容器但不启动它

docker create --name <新名称> <原名称>


启动、停止、杀死、重启 容器

docker stop <容器名orID>
docker start <容器名orID>
docker kill <容器名orID>
docker restart <容器名orID>


删除容器

docker rm <容器名orID>
docker rm $(docker ps -a -q) //删除所有


在运行的容器中执行命令

docker exec -it <容器名orID> /bin/bash


拷贝服务器中文件到容器内

docker cp /etc/apt/sources.list d9352a4fc865:/etc/apt/sources.list


把容器保存到镜像

docker commit -m "my apache" a404c6c174a2 mymysql



  • -a :提交的镜像作者;

  • -c :使用Dockerfile指令来创建镜像;

  • -m :提交时的说明文字;

  • -p :在commit时,将容器暂停。



容器操作



检查运行中的容器

docker ps 可以查看所有正在运行中的容器列表
docker ps -a为查看所有的容器,包括已经停止的。


可以查看更详细的关于某一个容器的信息

docker inspect <容器名orID>


查看容器中运行的进程信息

docker top <容器名orID>


列出指定的容器的端口映射

docker port <容器名orID>
深巷的酒
dare
又多了一台 ubuntu to...

又多了一台 ubuntu touch 的手机😄

又多了一台 ubuntu touch 的手机😄

dare

事隔多年,再次搞起ubuntu touch,好久不见。入手一台小米6x,刷上自己修改过的镜像,运行起docker,移动的服务器~

事隔多年,再次搞起ubuntu touch,好久不见。入手一台小米6x,刷上自己修改过的镜像,运行起docker,移动的服务器~

技术小牛钱小白

operation中docker基本原理相关说明??

参考:https://zhuanlan.zhihu.com/p/357946723

【docker原理】:https://www.cnblogs.com/wujianming-110117/p/14553175.html

??

??

参考:https://zhuanlan.zhihu.com/p/357946723

【docker原理】:https://www.cnblogs.com/wujianming-110117/p/14553175.html

??

??

跟老刘学python

新猿0基础python教程 uwsgi启动Python的Web项目中不要使用全局变量

# 一 使用uwsgi部署python的web项目

```python

一般在部署Django或者Flask时,我们为了利用多核优势,一般使用uwsgi部署,原理如下

如果我们设定uwsgi进程数为3,那么操作系统是开启3个进程来运行python的web程序

如果我们在web项目中使用全局变量,由于多进程间数据是隔离的,所以定义的全局变量,分别在3个进程中

```

# 二 测试

## 2.1 写一个flask程序(s1.py)

```python

from flask import Flask

import time

app = Flask...

# 一 使用uwsgi部署python的web项目

```python

一般在部署Django或者Flask时,我们为了利用多核优势,一般使用uwsgi部署,原理如下

如果我们设定uwsgi进程数为3,那么操作系统是开启3个进程来运行python的web程序

如果我们在web项目中使用全局变量,由于多进程间数据是隔离的,所以定义的全局变量,分别在3个进程中

```

# 二 测试

## 2.1 写一个flask程序(s1.py)

```python

from flask import Flask

import time

app = Flask(__name__)

count = 0

@app.route('/')

def hello_world():

    global count

    count+=1

    return 'Hello World!'+str(count)

if __name__ == '__main__':

    app.run(host='0.0.0.0')

```

## 2.2 编写uwsgi的配置文件 (uwsgi.ini)

```python

[uwsgi]

http = 0.0.0.0:5000

chdir = /root/

wsgi-file = /root/s1.py

processes = 1

threads = 2

buffer-size = 32768

master = true

pidfile = uwsgi.pid

daemonize = uwsgi.log

callable = app

# uwsgi uwsgi.ini  使用一个进程启动uwsgi

```

## 2.2 自己机器压测代码

```python

import requests

from threading import Thread

import time

def task():

    res=requests.get('http://101.133.225.166:5000/')

    print(res.text)

if __name__ == '__main__':

    for i in range(1000):

        t=Thread(target=task)

        t.start()

        # time.sleep(0.9)


 # 如果使用1个进程启动uwsgi,可以看到返回的数据中不会有重复的数字

# 但如果使用多个进程启动uwsgi,可以看到返回的数据中会有重复的数据,由于不同的进程中同一个变量不共享

# 如果使用python s1.py 就是一个进程运行,也不会有重复的数据

```


跟老刘学python

新猿0基础python教程 Linux入门介绍

# 一 什么是操作系统

```python

Operating System(操作系统) 简称OS

Windows,MacOS,Linux都是操作系统

```

# 二 什么是BootLoader

```python

# 在嵌入式操作系统中,BootLoader是在操作系统内核运行之前运行。可以初始化硬件设备、建立内存空间映射图,从而将系统的软硬件环境带到一个合适状态,以便为最终调用操作系统内核准备好正确的环境

# 一般在计算机启动的时候,选择启动Linux还是Windows的BootLoader是GRUB...

# 一 什么是操作系统

```python

Operating System(操作系统) 简称OS

Windows,MacOS,Linux都是操作系统

```

# 二 什么是BootLoader

```python

# 在嵌入式操作系统中,BootLoader是在操作系统内核运行之前运行。可以初始化硬件设备、建立内存空间映射图,从而将系统的软硬件环境带到一个合适状态,以便为最终调用操作系统内核准备好正确的环境

# 一般在计算机启动的时候,选择启动Linux还是Windows的BootLoader是GRUB

# 如果没有选择,GRUB会在几秒后启动默认的操作系统

# 双操作系统启动流程如下图

```

# 三 Linux和Windows的软件

```python

# windows系统下的软件,不能在Linux上运行,Linux上的软件不能在windows上运行

# Linux上的软件,基本上都是免费的

# Linux上软件,更新更频繁,且免费

# Linux上软件,效率更高

```

# 四 操作系统发展

```python

# 1984年,微软发布了第一个操作系统-->MS-DOS

    -1980年,西雅图电脑产品公司(Seattle Computer Products)的一名24岁的程序员蒂姆·帕特森(Tim Paterson)花费了四个月时间编写出了86-DOS操作系统

    -在1981年7月27日,比尔盖茨完全获得了一个叫做Seattle Computer Systems(西雅图计算机系统公司)的“Quick and Dirty Operating System”,简称QDOS的授权,花费5w美元。后来该操作系统被称作MS-DOS



# 同时代,1969年(1970年,计算机元年)起,也有一款比较出名的操作系统交Unix

    -1968年 Multics项目

    -MIT、Bell实验室、美国通用电气有限公司走到了一起,致力于开发Multics项目。到后期由于开发进度不是很好,MIT和Bell实验室相继离开这个项目的开发,最终导致项目搁浅。

    -1970年(Unix元年,时间戳) Unix诞生

    -当时在开发Multics项目的时候,实验室中有一个开发成员开发了一款游戏(travel space:遨游太空),因为两个实验室相继离开项目开发,导致这名开发人员没法玩游戏,后来他提议组织人员重新在Multics项目之上重新的开发,也就出现了1970年的Unix。当时Unix操作系统是使用的汇编语言(机器语言)开发的。

    -1973年 用C语言重写Unix

    -因为汇编语言有一个最大的局限性:对于计算机硬件过于依赖。导致移植性不好,所以后期在1973年使用了C语言对其进行重新开发。

    -1975年 Bell实验室允许大学使用Unix。

    -1975年,bell实验室允许大学使用Unix操作系统用于教学作用,而不允许用于商业用途。

# 在1984年,微软发布DOS的同时,理查德·马修·斯托曼(Richard Matthew Stallman, RMS)创立了GUN项目 

     -GNU项目 (牛羚),GNU is not Unix的缩写,目的是创建一个类Unix的操作系统,因为unix不是免费的,商业收费,刚开始学校教学免费使用,后来不免费了,价格比较贵(MacOS是类Unix操作系统)

   -理查德·马修·斯托曼:1953年出生,自由软件运动的精神领袖、GNU计划以及自由软件基金会(Free Software Foundation)的创立者、著名黑客,代表作:Emacs编辑器,GCC编译器,GDB调试器


 # 自由的和免费的

        -自由的意味着源代码必须公开(windows和macos是私有的),

      -自由软件大部分是免费的,但是可以复制,修改,出售


# 1991年 Linux的开发作者,Linux之父,李纳斯·托瓦兹。Linux诞生时是荷兰在校大学生。

    -1991年 0.0.1版本

    -李纳斯当时学校使用的就是Unix操作系统,然后其对系统的底层代码进行了修改,放到了学校为学生开放的网站上,原先他把文件命名写成了Linus’s Unix,后期网络管理发现之后觉得这个名字不好,自己手动的将名字改成Linux。随后其他同学下载之后发现这个版本还是挺好用的,随后都把自己代码贡献给李纳斯。

    -1992年 0.0.2版本

    -1994年 1.0版本

    -2003年 2.6版本

# Linux吉祥物企鹅

    -李纳斯以前在澳大利亚被一只企鹅咬过


```

# 五 Linux和GNU的联系

```python

# 这两个项目是互补的,Linus其实就写了一个类Unix内核

# 1991年GNU项目已经创建了不少操作系统外网软件,比如cp命令,rm命令,GCC,GDB等--》好比Linux就是人的骨骼,GUN就是血肉

# 后来完善Linux的工作就由Linus和广大开源社区的黑客们

# GNU项目+Linux内核=完整的操作系统,我们现在叫的Linux一般都是指GUN项目+Linux内核

```

![img](https://tva1.sinaimg.cn/large/008i3skNgy1gw3bww0842j30460460sm.jpg)

# 六 Linux内核

```python

上述所提及的版本号并不是分支版本,而是指Linux的内核版本。

Linux内核网站(现在最新5.x版本,3.x多一些,原来2.x多,现在docker要跑在3上)

https://www.kernel.org/

```

# 七 各个操作系统的关系

```python

# MacOS和Linux是基于Unix的意思是复刻了Unix的运行模式,源代码是不通的

# 目前Windows的版本是基于革命性的Windows NT内核

```

# 八 Linux发行版和区别

```python

# 因为Linux是开源自由软件,所以基于开源的代码可以定制属于自己的Linux系统,所以Linux的版本特别多

# Linux不同发行版的区别

    -安装方式不一样,有的简单,有的复杂

  -安装应用程序的方式也不一样 

  -预装的应用程序不一样


# 不同发行版使用的Linux内核一样

    -我们现在说的Linux其实都是指的是发行版(Distribution version),就是使用Linux内核加上各种GNU的库文件、应用程序,构造而成的操作系统

    -可以想象成同一个人(Linux内核),穿不通的衣服裙子羽绒服(软件)


# 不同发行版有的免费,有的收费

# 不同发行版

    -Red Hat:性能稳定,老牌的Linux发行版,RHEL收费,是red hat的企业版,源代码是开放的,收费是因为长期升级更新服务

  -现在Red Hat分两个系列:一个是red hat公司提供收费技术支持的RHEL,另一个是社区开放的免费版Fedora,每半年发行一次,由于发行频繁导致性能不太稳定,企业一般不选用Fedora

  -Centos:算是RHEL的克隆版,社区企业级操作系统, 改与Redhat, 完全开源,兼具社区和企业特性,融合了Fedora和redhat优点,长期支持,大规模使用稳定,企业普遍使用,特别适合做服务器

  -Deepin:深度,中国发行

  -Debian:迄今为止,最遵循GUN规范的Linux系统

  -Ubuntu :Debian一个后继或分支,社区维护, 现在主要做手机系统和电脑桌面系统。

```

```mermaid

graph TD;

    Linux--> Debian

    Linux--> RedHat

    Linux--> Deepin深度

    RedHat--> RHEL

    RedHat--> CentOS

    RedHat--> Fedora

```


跟老刘学python

新猿0基础python教程 如何写好接口文档_2

# 如何写好接口文档

# 1 HTTP携带信息的方式

- url

- headers

- body: 包括请求体,响应体

# 2 分离通用信息

一般来说,headers里的信息都是通用的,可以提前说明,作为默认参数

# 3 路径中的参数表达式

URL中参数表达式使用[mustache](https://github.com/janl/mustache.js)的形式,参数包裹在双大括号之中`{{paramName}}`

例如:

- `/api/user/{{userId}}`

- `/api/user/{{userType}}?age...

# 如何写好接口文档

# 1 HTTP携带信息的方式

- url

- headers

- body: 包括请求体,响应体

# 2 分离通用信息

一般来说,headers里的信息都是通用的,可以提前说明,作为默认参数

# 3 路径中的参数表达式

URL中参数表达式使用[mustache](https://github.com/janl/mustache.js)的形式,参数包裹在双大括号之中`{{paramName}}`

例如:

- `/api/user/{{userId}}`

- `/api/user/{{userType}}?age={{age}}&gender={{gender}}`

# 4 数据模型定义

数据模型定义包括:

- 路径与查询字符串参数模型

- 请求体参数模型

- 响应体参数模型

数据模型的最小数据集:

- 名称

- 是否必须

- 说明

> “最小数据集”(MDS)是指通过收集最少的数据,较好地掌握一个研究对象所具有的特点或一件事情、一份工作所处的状态,其核心是针对被观察的对象建立起一套精简实用的数据指标。最小数据集的概念起源于美国的医疗领域。最小数据集的产生源于信息交换的需要,就好比上下级质量技术监督部门之间、企业与质量技术监督部门之间、质量技术监督部门与社会公众之间都存在着信息交换的需求。

一些文档里可能会加入字段的类型,但是我认为这是没必要的。以为HTTP传输的数据往往都需要序列化,大部分数据类型都是字符串。一些特殊的类型,例如枚举类型的字符串,可以在说明里描述。

另外:`数据模型非常建议使用表格来表现`。

举个栗子?:

| 名称     | 是否必须 | 说明                                             |

| -------- | -------- | ------------------------------------------------ |

| userType | 是       | 用户类型。`commom`表示普通用户,`vip`表示vip用户 |

| age      | 否       | 用户年龄                                         |

| gender   | 否       | 用户性别。`1`表示男,`0`表示女                   |

# 5 请求示例

```

// general

POST http://www.testapi.com/api/user

// request payload

{

    "name": "qianxun",

    "age": 14,

    "like": ["music", "reading"],

    "userType": "vip"

}

// response

{

    "id": "asdkfjalsdkf"

}

```

# 6 异常处理

异常处理最小数据集

- 状态码

- 说明

- 解决方案

举个栗子?:

| 状态码 | 说明             | 解决方案                   |

| ------ | ---------------- | -------------------------- |

| 401    | 用户名密码错误   | 检查用户名密码是否正确     |

| 424    | 超过最大在线数量 | 请在控制台修改最大在线数量 |

之前我一直不想把解决方案加入异常处理的最小数据集,但是对于很多开发者来说,即使它知道`424`代表`超过最大在线数量`。如果你不告诉如果解决这个问题,那么他们可能就会直接来问你。所以最好能够一步到位,直接告诉他应该如何解决,这样省时省力。

# 7 如何组织?

## 7.1 一个创建用户的例子:创建用户

**1 请求示例**

```

// general

POST http://www.testapi.com/api/user/vip/?token=abcdefg

// request payload

{

    "name": "qianxun",

    "age": 14,

    "like": ["music", "reading"]

}

// response

{

    "id": "asdkfjalsdkf"

}

```

**2 路径与查询字符串参数模型**

`POST http://www.testapi.com/api/user/{{userType}}/?token={{token}}`

| 名称     | 是否必须 | 说明                                             |

| -------- | -------- | ------------------------------------------------ |

| userType | 是       | 用户类型。`commom`表示普通用户,`vip`表示vip用户 |

| token    | 是       | 认证令牌                                         |

**3 请求体参数模型**

| 名称 | 是否必须 | 说明               |

| ---- | -------- | ------------------ |

| name | 是       | 用户名。4-50个字符 |

| age  | 否       | 年龄               |

| like | 否       | 爱好。最多20个     |

**4 响应体参数模型**

| 名称 | 说明   |

| ---- | ------ |

| id   | 用户id |

**5 异常处理**

| 状态码 | 说明               | 解决方案                   |

| ------ | ------------------ | -------------------------- |

| 401    | token过期          | 请重新申请token            |

| 424    | 超过最大在创建人数 | 请在控制台修改最大创建人数 |

## 7.2 这样组织的原因

1. `请求示例`: 请求示例放在第一位的原因是,要用`最快的方式`告诉开发者,这个接口应该如何请求

2. `路径与查询字符串参数模型`: 使用`mustache`包裹参数

3. `请求体参数模型`:如果没有请求体,可以不写

4. `响应体参数模型`:

5. `异常处理`

# 8 文档提供的形式

文档建议由一下两种形式,`在线文档`,`pdf文档`。

- `在线文档`

  - 更新方便

  - 易于随时阅读

  - 易于查找

- `pdf文档`

  - 内容表现始终如一,不依赖文档阅读器

  - 文档只读,不会被轻易修改

其中由于是面对第三方开发者,`公开的在线文档必须提供`;由于某些特殊的原因,可能需要提供文件形式的文档,建议提供pdf文档。当然,以下的文档形式是`非常不建议`提供的:

- word文档

- markdown文档

word文档和markdown文档有以下缺点:

- `文档的表现形式非常依赖文档查看器`:各个版本的word文档对word的表现形式差异很大,可能在你的电脑上内容表现很好的文档,到别人的电脑上就会一团乱麻;另外markdown文件也是如此。而且markdown中引入文件只能依靠图片链接,如果文档中含有图片,很可能会出现图片丢失的情况。

- `文档无法只读`:文档无法只读,就有可能会被第三方开发者在不经意间修改,那么文档就无法保证其准确性了。

总结一下,文档形式的要点:

- `只读性`:保证文档不会被开发者轻易修改

- `一致性`:保证文档在不同设备,不同文档查看器上内容表现始终如一

- `易于版本管理`:文档即软件(DAAS: Document as a Software),一般意义上说`软件 = 数据 + 算法`, 但是我认为`文档也是一种组成软件的重要形式`。既然软件需要版本管理,文档的版本管理也是比不可少的。


跟老刘学python

新猿0基础python教程 接口的幂等性

“幂”相信学计算机的都对此不陌生,想要学习接口基本都会运用到这个,下面我们就来系统的学习接口的幂等性。

# 接口的幂等性

## **什么是幂等性**

幂等性是系统服务对外一种承诺,承诺只要调用接口成功,外部多次调用对系统的影响是一致的。声明为幂等的服务会认为外部调用失败是常态,并且失败之后必然会有重试。

## **什么情况下需要幂等**

以SQL为例:

SELECT col1 FROM tab1 WHER col2=2,无论执行多少次都不会改变状态,是天然的幂等。

UPDATE tab1 SET col1=1 WHERE col2=2,无论执行成功多...

“幂”相信学计算机的都对此不陌生,想要学习接口基本都会运用到这个,下面我们就来系统的学习接口的幂等性。

# 接口的幂等性

## **什么是幂等性**

幂等性是系统服务对外一种承诺,承诺只要调用接口成功,外部多次调用对系统的影响是一致的。声明为幂等的服务会认为外部调用失败是常态,并且失败之后必然会有重试。

## **什么情况下需要幂等**

以SQL为例:

SELECT col1 FROM tab1 WHER col2=2,无论执行多少次都不会改变状态,是天然的幂等。

UPDATE tab1 SET col1=1 WHERE col2=2,无论执行成功多少次状态都是一致的,因此也是幂等操作。

UPDATE tab1 SET col1=col1+1 WHERE col2=2,每次执行的结果都会发生变化,这种不是幂等的。

insert into user(userid,name) values(1,'a') 如userid为唯一主键,即重复操作上面的业务,只会插入一条用户数据,具备幂等性。

如userid不是主键,可以重复,那上面业务多次操作,数据都会新增多条,不具备幂等性。

delete from user where userid=1,多次操作,结果一样,具备幂等性

## **如何保证幂等**

**token机制**

1、服务端提供了发送token的接口。我们在分析业务的时候,哪些业务是存在幂等问题的,就必须在执行业务前,先去获取token,服务器会把token保存到redis中。

2、然后调用业务接口请求时,把token携带过去,一般放在请求头部。

3、服务器判断token是否存在redis中,存在表示第一次请求,然后删除token,继续执行业务。

4、如果判断token不存在redis中,就表示是重复操作,直接返回重复标记给client,这样就保证了业务代码,不被重复执行。

**关键点 先删除token,还是后删除token。**

后删除token:如果进行业务处理成功后,删除redis中的token失败了,这样就导致了有可能会发生重复请求,因为token没有被删除。这个问题其实是数据库和缓存redis数据不一致问题,后续会写文章进行讲解。

先删除token:如果系统出现问题导致业务处理出现异常,业务处理没有成功,接口调用方也没有获取到明确的结果,然后进行重试,但token已经删除掉了,服务端判断token不存在,认为是重复请求,就直接返回了,无法进行业务处理了。

先删除token可以保证不会因为重复请求,业务数据出现问题。出现业务异常,可以让调用方配合处理一下,重新获取新的token,再次由业务调用方发起重试请求就ok了。

**token机制缺点**

业务请求每次请求,都会有额外的请求(一次获取token请求、判断token是否存在的业务)。其实真实的生产环境中,1万请求也许只会存在10个左右的请求会发生重试,为了这10个请求,我们让9990个请求都发生了额外的请求。

**乐观锁机制**

这种方法适合在更新的场景中,`update t_goods set count = count -1 , version = version + 1 where good_id=2 and version = 1`

根据version版本,也就是在操作库存前先获取当前商品的version版本号,然后操作的时候带上此version号。我们梳理下,我们第一次操作库存时,得到version为1,调用库存服务version变成了2;但返回给订单服务出现了问题,订单服务又一次发起调用库存服务,当订单服务传如的version还是1,再执行上面的sql语句时,就不会执行;因为version已经变为2了,where条件就不成立。这样就保证了不管调用几次,只会真正的处理一次。

乐观锁主要使用于处理读多写少的问题

**唯一主键**

这个机制是利用了数据库的主键唯一约束的特性,解决了在insert场景时幂等问题。但主键的要求不是自增的主键,这样就需要业务生成全局唯一的主键。

如果是分库分表场景下,路由规则要保证相同请求下,落地在同一个数据库和同一表中,要不然数据库主键约束就不起效果了,因为是不同的数据库和表主键不相关。

**防重表**

使用订单号orderNo做为去重表的唯一索引,把唯一索引插入去重表,再进行业务操作,且他们在同一个事务中。这个保证了重复请求时,因为去重表有唯一约束,导致请求失败,避免了幂等问题。这里要注意的是,去重表和业务表应该在同一库中,这样就保证了在同一个事务,即使业务操作失败了,也会把去重表的数据回滚。这个很好的保证了数据一致性。

**唯一ID**

调用接口时,生成一个唯一id,redis将数据保存到集合中(去重),存在即处理过。

**唯一ID机制 **

调用者生成一个唯一ID


跟老刘学python

新猿0基础python教程 如何写好接口文档

同学们学习python的时候接口文档是比较重要的,接口文档的问题直接影响到我们后续接口的调用以及使用,那么下面我们一起来认真学习下如何写好接口文档。

# 1 HTTP携带信息的方式

- url

- headers

- body: 包括请求体,响应体

# 2 分离通用信息

一般来说,headers里的信息都是通用的,可以提前说明,作为默认参数

# 3 路径中的参数表达式

URL中参数表达式使用[mustache](https://github.com/janl/mustache.js)的形式,参数包裹在双大括号之中`{{paramName}}`

例如:

- ...

同学们学习python的时候接口文档是比较重要的,接口文档的问题直接影响到我们后续接口的调用以及使用,那么下面我们一起来认真学习下如何写好接口文档。

# 1 HTTP携带信息的方式

- url

- headers

- body: 包括请求体,响应体

# 2 分离通用信息

一般来说,headers里的信息都是通用的,可以提前说明,作为默认参数

# 3 路径中的参数表达式

URL中参数表达式使用[mustache](https://github.com/janl/mustache.js)的形式,参数包裹在双大括号之中`{{paramName}}`

例如:

- `/api/user/{{userId}}`

- `/api/user/{{userType}}?age={{age}}&gender={{gender}}`

# 4 数据模型定义

数据模型定义包括:

- 路径与查询字符串参数模型

- 请求体参数模型

- 响应体参数模型

数据模型的最小数据集:

- 名称

- 是否必须

- 说明

> “最小数据集”(MDS)是指通过收集最少的数据,较好地掌握一个研究对象所具有的特点或一件事情、一份工作所处的状态,其核心是针对被观察的对象建立起一套精简实用的数据指标。最小数据集的概念起源于美国的医疗领域。最小数据集的产生源于信息交换的需要,就好比上下级质量技术监督部门之间、企业与质量技术监督部门之间、质量技术监督部门与社会公众之间都存在着信息交换的需求。

一些文档里可能会加入字段的类型,但是我认为这是没必要的。以为HTTP传输的数据往往都需要序列化,大部分数据类型都是字符串。一些特殊的类型,例如枚举类型的字符串,可以在说明里描述。

另外:`数据模型非常建议使用表格来表现`。

举个栗子?:

| 名称     | 是否必须 | 说明                                             |

| -------- | -------- | ------------------------------------------------ |

| userType | 是       | 用户类型。`commom`表示普通用户,`vip`表示vip用户 |

| age      | 否       | 用户年龄                                         |

| gender   | 否       | 用户性别。`1`表示男,`0`表示女                   |

# 5 请求示例

```

// general

POST http://www.testapi.com/api/user

// request payload

{

    "name": "qianxun",

    "age": 14,

    "like": ["music", "reading"],

    "userType": "vip"

}

// response

{

    "id": "asdkfjalsdkf"

}

```

# 6 异常处理

异常处理最小数据集

- 状态码

- 说明

- 解决方案

举个栗子?:

| 状态码 | 说明             | 解决方案                   |

| ------ | ---------------- | -------------------------- |

| 401    | 用户名密码错误   | 检查用户名密码是否正确     |

| 424    | 超过最大在线数量 | 请在控制台修改最大在线数量 |

之前我一直不想把解决方案加入异常处理的最小数据集,但是对于很多开发者来说,即使它知道`424`代表`超过最大在线数量`。如果你不告诉如果解决这个问题,那么他们可能就会直接来问你。所以最好能够一步到位,直接告诉他应该如何解决,这样省时省力。

# 7 如何组织?

## 7.1 一个创建用户的例子:创建用户

**1 请求示例**

```

// general

POST http://www.testapi.com/api/user/vip/?token=abcdefg

// request payload

{

    "name": "qianxun",

    "age": 14,

    "like": ["music", "reading"]

}

// response

{

    "id": "asdkfjalsdkf"

}

```

**2 路径与查询字符串参数模型**

`POST http://www.testapi.com/api/user/{{userType}}/?token={{token}}`

| 名称     | 是否必须 | 说明                                             |

| -------- | -------- | ------------------------------------------------ |

| userType | 是       | 用户类型。`commom`表示普通用户,`vip`表示vip用户 |

| token    | 是       | 认证令牌                                         |

**3 请求体参数模型**

| 名称 | 是否必须 | 说明               |

| ---- | -------- | ------------------ |

| name | 是       | 用户名。4-50个字符 |

| age  | 否       | 年龄               |

| like | 否       | 爱好。最多20个     |

**4 响应体参数模型**

| 名称 | 说明   |

| ---- | ------ |

| id   | 用户id |

**5 异常处理**

| 状态码 | 说明               | 解决方案                   |

| ------ | ------------------ | -------------------------- |

| 401    | token过期          | 请重新申请token            |

| 424    | 超过最大在创建人数 | 请在控制台修改最大创建人数 |

## 7.2 这样组织的原因

1. `请求示例`: 请求示例放在第一位的原因是,要用`最快的方式`告诉开发者,这个接口应该如何请求

2. `路径与查询字符串参数模型`: 使用`mustache`包裹参数

3. `请求体参数模型`:如果没有请求体,可以不写

4. `响应体参数模型`:

5. `异常处理`

# 8 文档提供的形式

文档建议由一下两种形式,`在线文档`,`pdf文档`。

- `在线文档`

  - 更新方便

  - 易于随时阅读

  - 易于查找

- `pdf文档`

  - 内容表现始终如一,不依赖文档阅读器

  - 文档只读,不会被轻易修改

其中由于是面对第三方开发者,`公开的在线文档必须提供`;由于某些特殊的原因,可能需要提供文件形式的文档,建议提供pdf文档。当然,以下的文档形式是`非常不建议`提供的:

- word文档

- markdown文档

word文档和markdown文档有以下缺点:

- `文档的表现形式非常依赖文档查看器`:各个版本的word文档对word的表现形式差异很大,可能在你的电脑上内容表现很好的文档,到别人的电脑上就会一团乱麻;另外markdown文件也是如此。而且markdown中引入文件只能依靠图片链接,如果文档中含有图片,很可能会出现图片丢失的情况。

- `文档无法只读`:文档无法只读,就有可能会被第三方开发者在不经意间修改,那么文档就无法保证其准确性了。

总结一下,文档形式的要点:

- `只读性`:保证文档不会被开发者轻易修改

- `一致性`:保证文档在不同设备,不同文档查看器上内容表现始终如一

- `易于版本管理`:文档即软件(DAAS: Document as a Software),一般意义上说`软件 = 数据 + 算法`, 但是我认为`文档也是一种组成软件的重要形式`。既然软件需要版本管理,文档的版本管理也是比不可少的。


跟老刘学python

0基础python教程 各主流Linux系统解决pip安装mysqlclient报错

不少同学经常使用windows系统但是在linux系统中不知道如何解决问题,本章节就为你解析在Linux系统解决pip安装mysqlclient报错如何解决。

---

title: "各主流Linux系统解决pip安装mysqlclient报错"

date: 2020-02-10 23:10

tags:

 - Python

---

##   一 CentOS(红帽)

```python

#CentOS有Python、Mysql的开发工具包,安装后使用pip安装mysqlclient即可

yum install...

不少同学经常使用windows系统但是在linux系统中不知道如何解决问题,本章节就为你解析在Linux系统解决pip安装mysqlclient报错如何解决。

---

title: "各主流Linux系统解决pip安装mysqlclient报错"

date: 2020-02-10 23:10

tags:

 - Python

---

##   一 CentOS(红帽)

```python

#CentOS有Python、Mysql的开发工具包,安装后使用pip安装mysqlclient即可

yum install mysql-devel

yum install python-devel

#yum install python36-devel

pip install mysqlclient

```

## 二  Ubuntu

```python

#Ubuntu的话,也是安装一些Mysql的依赖或开发库

apt-get install libmysql-dev

apt-get install libmysqlclient-dev

apt-get install python-dev #python3要装python3-dev

pip install mysqlclient

#此时如果遇到如下错误

Collecting mysqlclient

  Using cached  https://files.pythonhosted.org/packages/f4/f1/3bb6f64ca7a429729413e6556b7ba5976df06019a5245a43d36032f1061e/mysqlclient-1.4.2.post1.tar.gz

   Complete output from command python setup.py egg_info:

   Traceback (most recent call last):

    File "<string>", line 1, in <module>

   ModuleNotFoundError: No module named 'setuptools'


   \----------------------------------------

Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-p8wpb1kf/mysqlclient/

#需要安装一下setuptools包,直接pip install setuptools==33.1.1,python3的话就pip3,看你的系统。

```

## 三 Windows

```python

#win下看人品,人品好直接成功,人品不好就废,在win下的话解决方案很多:

#1 anaconda

直接下载使用anaconda,创建虚拟环境来进行开发

#2 whl包安装

#或者到pipy下载相对应的whl包,使用pip安装即可,具体包的版本和适用平台自行查询就好

到这个地址下载自己版本对应的资源

https://www.lfd.uci.edu/~gohlke/pythonlibs/#mysqlclient

#查看是否成功

#直接使用pip list命令查看所有已安装包,确定是否安装成功,效果如下:

pip list

Package        Version

-------------------- --------

 ...... 

mysqlclient      1.4.2  

 ......

 有的话就表明安装成功。

```


跟老刘学python

0基础python教程 各主流Linux系统解决pip安装mysqlclient报错

---
title: "各主流Linux系统解决pip安装mysqlclient报错"
date: 2020-02-10 23:10
tags:
 - Python
---

##   一 CentOS(红帽)

```python
#CentOS有Python、Mysql的开发工具包,安装后使用pip安装mysqlclient即可
yum install mysql-devel
yum install python-devel
#yum install python36-devel
pip install mysqlclient
```

## ...

---
title: "各主流Linux系统解决pip安装mysqlclient报错"
date: 2020-02-10 23:10
tags:
 - Python
---

##   一 CentOS(红帽)

```python
#CentOS有Python、Mysql的开发工具包,安装后使用pip安装mysqlclient即可
yum install mysql-devel
yum install python-devel
#yum install python36-devel
pip install mysqlclient
```



## 二  Ubuntu

```python
#Ubuntu的话,也是安装一些Mysql的依赖或开发库
apt-get install libmysql-dev
apt-get install libmysqlclient-dev
apt-get install python-dev #python3要装python3-dev
pip install mysqlclient
#此时如果遇到如下错误

Collecting mysqlclient
  Using cached  https://files.pythonhosted.org/packages/f4/f1/3bb6f64ca7a429729413e6556b7ba5976df06019a5245a43d36032f1061e/mysqlclient-1.4.2.post1.tar.gz
   Complete output from command python setup.py egg_info:
   Traceback (most recent call last):
    File "<string>", line 1, in <module>
   ModuleNotFoundError: No module named 'setuptools'
   
   \----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-p8wpb1kf/mysqlclient/

#需要安装一下setuptools包,直接pip install setuptools==33.1.1,python3的话就pip3,看你的系统。


```



## 三 Windows

```python
#win下看人品,人品好直接成功,人品不好就废,在win下的话解决方案很多:
#1 anaconda
直接下载使用anaconda,创建虚拟环境来进行开发
#2 whl包安装
#或者到pipy下载相对应的whl包,使用pip安装即可,具体包的版本和适用平台自行查询就好
到这个地址下载自己版本对应的资源
https://www.lfd.uci.edu/~gohlke/pythonlibs/#mysqlclient
#查看是否成功
#直接使用pip list命令查看所有已安装包,确定是否安装成功,效果如下:
pip list
Package        Version

-------------------- --------
 ...... 
mysqlclient      1.4.2  
 ......
 有的话就表明安装成功。
```

跟老刘学python

0基础python教程 django的manage命令介绍

学习python中django框架的小伙伴一定不能错过本章节,一定要认真学习manage命令的运用介绍。

1 django的manage命令介绍

>
>
>我们在迁移数据库时会执行两条命令
>
>python3 manage.py makemigrations
>
>python3 manage.py migrate
>
>那我们可不可以自定制一个命令呢?当然是可以的

## 2 如何django的manage命令

> 我们可以参考内置app:auth的createsuperuser命令
>
> 需要在app路径下新建management...

学习python中django框架的小伙伴一定不能错过本章节,一定要认真学习manage命令的运用介绍。

1 django的manage命令介绍

>
>
>我们在迁移数据库时会执行两条命令
>
>python3 manage.py makemigrations
>
>python3 manage.py migrate
>
>那我们可不可以自定制一个命令呢?当然是可以的

## 2 如何django的manage命令

> 我们可以参考内置app:auth的createsuperuser命令
>
> 需要在app路径下新建management包
>
> 在management包下新建commands包
>
> 在commands包新建py文件

![image-20210428160501402](/Users/liuqingzheng/Library/Application%20Support/typora-user-images/image-20210428160501402.png)

## 3 操作步骤

```python
# 1 新建项目 django_manage,新建app,名叫app01
# 2 在app01下新建需要在app路径下新建management包
# 3 在management包下新建commands包
# 4 在commands包新建py文件
# 5 新建hello_world.py,内容如下
```

```python
from django.core.management.base import BaseCommand


class Command(BaseCommand):
    help = '''
    这是自定义helloworld命令帮助信息
    使用方式为
        关键字参数方案:
        python3 manage.py hello_world --name=lqz --age=19
        python3 manage.py hello_world --name=lqz --age=19
        位置参数方案:
        python3 manage.py hello_world lqz 19
    '''
        # 接收参数
    def add_arguments(self, parser):
        # 关键字参数方案
        parser.add_argument('--name',help='这里输入名字')
        parser.add_argument('--age',help='这里输入年龄')
        # 位置参数方案
        # parser.add_argument('name')
        # parser.add_argument('age')
        
        # 核心函数,具体的逻辑写在这
    def handle(self, *args, **options):
        # 1 取出带在命令行后的参数
        input_name=options['name']
        print(input_name)

        #2 让用户在控制台输入
        name = input('输入你的狗名字:')
        if name.startswith('sb'):
            raise Exception('名字不能以sb开头')
        else:
            self.stdout.write('hello world:%s' % name)
            # print('hello world:%s'%name)

```

>在控制台输入:即可使用
>
>python3 manage.py hello_world --name=lqz --age=19

## 4 初始化数据命令案例

```python
我们在上线上面的时候,需要初始化一些数据进数据库,现在我们来写这么一个命令

```

跟老刘学python

0基础python教程 重学Git

看着标题很多的同学相信都会有疑问,为了要重学Git,之前难道学习的正确,没错,如果不是正确的学习Git后面遇到的问题就会很棘手,不知道如何去解决,就不能更好的运用Git,下面跟着老刘一起来重新学习Git吧!

## 1 Git介绍

```python

# Git的作用

1 对文件(代码)进行版本管理

2 完成 协同开发 项目,帮助程序员整合代码

    i)帮助开发者合并开发的代码

    ii)如果出现冲突代码的合并,会提示后提交合并代码的开发者,让其解决冲突

# Git简介

Git是分...

看着标题很多的同学相信都会有疑问,为了要重学Git,之前难道学习的正确,没错,如果不是正确的学习Git后面遇到的问题就会很棘手,不知道如何去解决,就不能更好的运用Git,下面跟着老刘一起来重新学习Git吧!

## 1 Git介绍

```python

# Git的作用

1 对文件(代码)进行版本管理

2 完成 协同开发 项目,帮助程序员整合代码

    i)帮助开发者合并开发的代码

    ii)如果出现冲突代码的合并,会提示后提交合并代码的开发者,让其解决冲突

# Git简介

Git是分布式版本控制系统,控制的对象是开发的项目代码

# 举例

比如你在写毕业论文,想删除一个段落,又怕将来想恢复找不回来怎么办?

于是你先把当前文件另存为一个新的文件,再接着改,改到一定程度,再另存为成另一个新文件,这样一直改下去,最后你的文件变成了:

    -毕业论文1.doc

  -毕业论文2.doc

  -毕业论文3.doc

  -毕业论文-永不修改版.doc

  -毕业论文-打死不改版.doc

  -毕业论文-再改去死版.doc


过了一段时间,你想找回被删除的文字,但是已经记不清删除前保存在哪个文件里了,只好一个一个文件去找

看着一堆乱七八糟的文件,想保留最新的一个,然后把其他的删掉,又怕哪天会用上,还不敢删

```

## 2 Git 和SVN

![img](https://tva1.sinaimg.cn/large/007S8ZIlgy1ggqvsye2khj30kj0a6mx3.jpg)

![img](https://tva1.sinaimg.cn/large/007S8ZIlgy1ggqvt8t61hj30m10da3yk.jpg)

**Git:分布式,无网络时也可以提交到本地版本库,待到有网络时再push到服务器. **

**svn:非分布式.无网络不可以提交**

## 3 Git,GitHub,GitLab,Gitee

```python

Git:是一种版本控制系统,是一个命令,是一种工具。

GitHub:是一个基于Git实现的在线代码托管仓库,包含一个网站界面,向互联网开放,公有仓库免费,部分私有仓库收费,全球最大的开源代码托管平台

GitLab:是一个基于Git实现的在线代码仓库托管软件,可以通过GitLab自己搭建一个类似于GitHub一样的系统,用在企业内部网络搭建Git私服,用于企业团队内部协作开发

Gitee:(码云) 是 OSCHINA 推出的代码托管平台,支持 Git 和 SVN,提供免费的私有仓库托管,面向互联网开发,分收费和付费,中国最大的开源代码托管平台

```

## 4 Git工作流程

![未命名文件 (1)](https://tva1.sinaimg.cn/large/008i3skNgy1guqseyffpoj60x40eqmyu02.jpg)

## 5 Git使用

### 5.1 流程(核心总结)

```python

"""

1)有红色信息(工作区有内容),就执行 add

2)全绿信息(内容全部在暂存区),才执行 commit

3)只有被版本库控制的代码,才能被监听,所以可以回滚到任何一个版本

"""

```

### 5.2 安装

```python

# 1.下载对应版本:https://git-scm.com/download

# 2.安装git:在选取安装路径的下一步选取 Use a TrueType font in all console windows 选项

```

### 5.3 基础命令

#### 将已有的文件夹 - 初始化为git仓库

```python

"""

>: cd 目标文件夹内部

>: git init

"""

```

#### 在指定目录下 - 初始化git仓库

```python

"""

>: cd 目标目录

>: git init 仓库名

"""

```

#### 在仓库目录终端下 - 设置全局用户

```python

"""

>: git config --global user.name '用户名'

>: git config --global user.email '用户邮箱'

注:在全局文件 C:\Users\用户文件夹\.gitconfig新建用户信息,在所有仓库下都可以使用

"""

```

#### 在仓库目录终端下 - 设置局部用户

```python

"""

>: git config user.name '用户名'

    -- 用户名

>: git config user.email '用户邮箱'

    -- 用户邮箱


注:在当前仓库下的config新建用户信息,只能在当前仓库下使用

注:一个仓库有局部用户,优先使用局部用户,没有配置再找全局用户

"""

```

#### 查看仓库状态

```python

"""

# 当仓库中有文件增加、删除、修改,都可以在仓库状态中查看

>: git status  

    -- 查看仓库状态

>: git status -s  

    -- 查看仓库状态的简约显示

"""

```

#### 工作区操作

```python

# 通过任何方式完成的文件删与改

# 空文件夹不会被git记录

```

#### 撤销工作区操作:改、删(了解)

```python

"""

>: git checkout .

    -- 撤销所有暂存区的提交

>: git checkout 文件名

    -- 撤销某一文件的暂存区提交

"""

```

#### 工作区内容提交到暂存区

```python

"""

>: git add .  

    -- 添加项目中所有文件

>: git add 文件名  

    -- 添加指定文件

"""

```

#### 撤销暂存区提交:add的逆运算(很少使用)

```python

"""

>: git reset HEAD .

    -- 撤销所有暂存区的提交

>: git reset 文件名

    -- 撤销某一文件的暂存区提交

>: git reset .

    -- 撤销所有暂存区的提交

"""

```

#### 提交暂存区内容到版本库

```python

>: git commit -m "版本描述信息"

```

#### 撤销版本库提交:commit的逆运算

```python

"""

回滚暂存区已经提交到版本库的操作:

    查看历史版本:

        >: git log

        >: git reflog

    查看时间点之前|之后的日志:

        >: git log --after 2018-6-1

        >: git log --before 2018-6-1

        >: git reflog --after 2018-6-1

        >: git reflog --before 2018-6-1

    查看指定开发者日志

        >: git log --author author_name

        >: git reflog --author author_name

    回滚到指定版本:

        回滚到上一个版本:

            >: git reset --hard HEAD^

            >: git reset --hard HEAD~

        回滚到上三个版本:

            >: git reset --hard HEAD^^^

            >: git reset --hard HEAD~3

        回滚到指定版本号的版本:

            >: git reset --hard 版本号 (重点)

            >: eg: git reset --hard 35cb292

"""

```

#### 扩展阅读

```python

# git log 和git reflog的区别

git log 命令可以显示所有提交过的版本信息

如果感觉太繁琐,可以加上参数  --pretty=oneline,只会显示版本号和提交时的备注信息

git reflog 可以查看所有分支的所有操作记录(包括已经被删除的 commit 记录和 reset 的操作)

# git reset --hard,--mix,--soft的区别

hard (硬)-> 全部删除,会彻底返回到回退前的版本状态,了无痕迹

mixed (中)-> 保留工作目录,文件回退到未commit的状态

soft (软)-> 保留工作目录、暂存区 ,文件会回退到未 add(未到暂存)的状态

总结:

soft是撤销commit的提交,但工作区未提交的更改还是保留;

mixed是撤销暂存区的提交,工作区的更改同样也保留;

而hard是把工作区、暂存区、commit到仓库的三个版本都回滚了

```

## 6 Git忽略文件

Git工作目录中,有些文件必须要有,但又不能提交它们,就可以设置忽略文件

在Git工作区的根目录下创建一个特殊的`.gitignore`文件,然后把要忽略的文件名放进去,Git就会自动忽略这些文件

```python

# .gitignore 文件

# 1)在仓库根目录下创建该文件

# 2)文件与文件夹均可以被过滤

# 3)文件过滤语法

""" 过滤文件内容

文件或文件夹名:代表所有目录下的同名文件或文件夹都被过滤

/文件或文件夹名:代表仓库根目录下的文件或文件夹被过滤

例如:

a.txt:项目中所有a.txt文件和文件夹都会被过滤

/a.txt:项目中只有根目录下a.txt文件和文件夹会被过滤

/b/a.txt:项目中只有根目录下的b文件夹下的a.txt文件和文件夹会被过滤

*x*:名字中有一个x的都会被过滤(*代表0~n个任意字符)

空文件夹不会被提交,空包会被提交,包可以被提交(包中有一个init空文件)

注意:

# 以'#'开始的行,被视为注释.                                                                                                                          

# 忽略掉所有文件名是 lqz.txt的文件.

    lqz.txt

# 忽略所有生成的 html文件,

*.html

# lqz.html是例外,不在忽略范围内

!lqz.html

# 忽略所有.o和 .a文件.

*.[oa]

"""

```

## 7 Git分支

### 7.1 基本使用

```python

"""

1.创建分支

git branch 分支名

2.查看分支

git branch

3.切换分支

git checkout 分支名

4.创建并切换到分支

git checkout -b 分支名

5.删除分支

git branch -d 分支名

6.查看远程分支(列出所有分支,包含远程)

git branch -a

7.合并分支

git merge 分支名

把dev分支合并到master分支:切换到master分支,执行合并dev分支的命令

8.删除远程分支

git push origin --delete lqz

9.新建远程分支

本地lqz分支建立完成

git push origin lqz

"""

"""

1)多个开发者都是在一个分支上进行开发,不出意外,该分支一定叫dev(协同开发)

2)如果出现一个特殊任务(敏感任务),与正常业务关系不紧密,甚至可能大的影响正常的dev分支开发,可以依赖dev开一个子分支,进行开发,开发完毕后合并到dev分支,再删除该分支即可

3)所有的开发任务都可以在dev分支上进行(除非公司硬性要求不能直接在dev分支开发,只能在dev子分支开发,测试通过后才能合并给dev)

"""

```

### 7.2 dev分支合并到master分支

![未命名文件 (2)](https://tva1.sinaimg.cn/large/008i3skNgy1guqz5c5882j60p107w0t002.jpg)

### 7.3 基于分支的线上bug修复(开发新功能,出现bug)

![未命名文件 (3)](https://tva1.sinaimg.cn/large/008i3skNgy1guqztf0lfvj60s70aqjry02.jpg)

```python

# 无冲突情况

git branch dev # 创建dev分支

git checkout dev # 切换到dev分支

vi d3.txt       # 新增d3.txt

git add .

git commit -m 'd3.txt' # 提交到版本库

git checkout master    # 切换到master分支

git branch bug         # 创建bug分支

git checkout bug       # 切换到bug分支

vi b4.txt              # 在bug分支,新增b4.txt  

git add .

git commit -m 'b4.txt'

git checkout master    # 切换回master分支

git merge bug          # 合并bug分支

git log

git merge dev          # 合并dev分支,无冲突,写注释

git log

```

```python

git branch -d dev

git branch -d bug

# 有冲突情况

git branch dev # 创建dev分支

git checkout dev # 切换到dev分支

vi d4.txt       # 新增d4.txt

git add .

git commit -m 'd4.txt' # 提交到版本库

git checkout master    # 切换到master分支

git branch bug         # 创建bug分支

git checkout bug       # 切换到bug分支

vi b4.txt              # 在bug分支,新增b4.txt  

git add .

git commit -m 'd4.txt'

git checkout master    # 切换回master分支

git merge bug          # 合并bug分支

git log

git merge dev          # 合并dev分支,出冲突

'''

CONFLICT (add/add): Merge conflict in d4.txt

Auto-merging d4.txt

Automatic merge failed; fix conflicts and then commit the result.

'''

# 打开d4.txt发现如下错误

<<<<<<< HEAD    # 原来代码

bug-add-d4

=======         # 新代码

sada

>>>>>>> dev

#  手动修复,解决冲突,再提交

git add .

git commit -m '解决冲突'

git log

```

## 8 Git远程仓库

**我们要协同开发,代码要提交到远程仓库,可以使用gitee,github,gitlab,本文以gitee为例**

### 8.1 创建远程仓库

```python

# 首先注册gitee账号,登陆后,创建仓库

```

**注意:git push -u origin master 中-u的意思是,只要执行一遍这个命令,以后执行git push 就等同于git push origin maste,所有-u表示设置一个默认 **

### 8.2 remote源操作

```python

"""

1)查看仓库已配置的远程源

>: git remote

>: git remote -v

2)查看remote命令帮助文档

>: git remote -h

3)删除远程源

>: git remote remove 源名

eg: git remote remove origin

4)添加远程源

>: git remote add 源名 源地址

>: git remote add orgin https://gitee.com/liuqingzheng/app01.git

5)提交代码到远程源

>: git push 源码 分支名

6)克隆远程源

>: git clone 远程源地址

"""

"""

1)通过克隆方式连接远程源,默认远程源名就叫origin;所以主动添加远程源来连接远程仓库,源码也用origin

2)本地一个仓库只需要和远程一个源进行同步,所以只需要连接一个远程源,如果还想把本地代码同步给第三个平台,那么可以通过主动添加远程源来连接第三个平台的远程仓库,此时的源码就不能再叫origin了,比如online都可以

3)pull和push都可以提供选择不同的源码,和不同的远程仓库交互

"""

```

### 8.3 采用ssh协议连接远程源

```python

# 生成公钥私钥,帮助文档

官网:https://gitee.com/help/articles/4181#article-header0

# 在命令行下执行命令

ssh-keygen -t rsa -C "306334678@qq.com" # 邮箱可以任意填写

# 生成的公钥私钥,会放在用户家路径下的.ssh文件夹下

本机命令,查看公钥:cat ~/.ssh/id_rsa.pub

# 复制公钥,粘贴到gitee上配置

    -项目仓库 => 管理 => 部署公钥管理 => 添加公钥 => 添加个人公钥


# 把原来的 origin删除,新增ssh源

git remote remove orgin

git remote add orgin git@gitee.com:liuqingzheng/app01.git


# 配置成功后,再拉取和提交代码,不需要输入用户名密码认证了

```

### 8.4 如何成为其他码云项目的开发者

```python

如果公司项目已经存在,同事新入职,基于原项目开发

"""

1)生成自己电脑的公钥,配置到自己的码云个人公钥中

2)把自己的码云用户名提供给别人,别人添加你成为项目开发者

3)自己确认添加,成为开发者,克隆开发项目,进行开发

"""

```

### 8.5 协同开发

```python

"""

1)作为开发者,第一次同步项目

>: git clone 项目地址

2)保证自己本地有dev分支,且与远程仓库版本同步(没有就自己新建)

3)本地开发的代码,必须add、commit到本地版本库后,才和远程仓库进行交互

4)交互顺序:必须 先拉(pull)后提(push)

5)必须切换到要交互的分支,在与远程同名的分支进行交互,如本地dev与远程dev交互

>: git checkout dev

>: git add .

>: git commit -m '本次提交的信息提示'

>: git pull origin dev

>: git push origin dev

"""

```

### 8.6 线上分支合并(提交pr)

#### 无冲突情况

```python

# 本地创建分支

git branch dev

# 把本地分支提交到远程

git push  origin dev

# 在本地dev分支修改代码

git checkout dev

vi d5.txt

git add .

git commit -m '新增d5'

# 推送到远程

git push  origin dev

```

![image-20210924002401179](https://tva1.sinaimg.cn/large/008i3skNgy1gur0wjexf0j61wa0eodi902.jpg)

![image-20210924002620931](https://tva1.sinaimg.cn/large/008i3skNgy1gur0yzez7aj61e60u041l02.jpg)

![image-20210924003103078](https://tva1.sinaimg.cn/large/008i3skNgy1gur13ujqipj61i80u0adt02.jpg)

#### 有冲突情况

```python

git pull origin master  # 主分支拉取最新

vi d5.txt

git add .

git commit -m '修改d5.txt'

git push  origin master  # 主分支修改一行,提交到远程

git checkout dev  # 切换到dev分支

vim d5.txt

git add .

git commit -m 'dev修改d5.txt'

git push  origin dev    # 修改同一行,提交到远程,注意同一行内容不能一致

## 线上提交pr,线上不能自动合并,需要手动合并

git checkout master

git pull https://gitee.com/liuqingzheng/app01.git dev

# 手动修改冲突

git add .

git commit -m '合并pr'

git push origin master

# 再去线上,看到分支已经合并好了

```

### 8.7 远程仓库回滚

```python

"""

用dev分支举例

1)本地切换到远程要回滚的分支对应的本地分支

git checkout dev

2)回滚本地分支

git reset --hard 版本号

3)本地版本强行提交给服务器

git push origin dev -f

"""

```

## 9 冲突解决

### 9.1 多人开发同一分支导致冲突

```python

"""

1)在远程仓库和本地仓库版本不一致时,拉取远程仓库版本到本地时,两个版本进入融合,可能会出现版本冲突

2)定位冲突文件冲突代码,线下沟通冲突代码,整合代码解决冲突

3)将解决冲突后的代码重新提交到本地版本库

4)再拉去远程仓库,直到没有冲突,提交本地版本库到远程

"""

"""

<<<<<<< HEAD  # 冲突的开始

# 自己的代码

=======  # 分割线

# 别人的代码

>>>>>>> b63c408abd05b87fc492d40523240561999dba50  # 冲突的结束(版本)

"""

"""

1)删除冲突相关标识:冲突的开始、分割线、冲突的结束(版本)

2)线下沟通,根据实际需求完成代码整合

3)测试整合后的代码

"""

"""

出现冲突的前提:

1)不同开发者同时操作了同一文件

2)并且在相同行写了代码

强调:有业务交际时,版本合并不一定会出现冲突相关的标识,但是可能会带着代码运行崩溃,所有理论上每一次版本合并,都要测试合并后的所有功能(及其之少的情况)

"""

```

### 9.2 分支合并导致冲突

```python

分支合并出现冲突效果跟上面一样,只需要解决冲突,重新提交即可

"""

<<<<<<< HEAD  # 冲突的开始

# 自己的代码

=======  # 分割线

# 别人的代码

>>>>>>> dev  # 冲突的分支

"""

```

## 10 同一个人在公司开发和在家开发

### 10.1 正常情况

```python

# 公司电脑,有代码

git branch lqz

git checkout lqz # 创建一个自己的分支,写代码

vi new.txt

git add .

git commit -m '公司开发了'

git push origin lqz

# 家里电脑,没有代码,需要先克隆

cd Desktop/proj

git clone https://gitee.com/liuqingzheng/app01.git

cd app01

git pull origin lqz #拉取lqz分支内容

git checkout lqz    # 切换到lqz分支

# 基于此继续开发,公司开发的代码也拉下来了,写完记得提交到远程

# 到了公司只需要再pull一下即可把家中开发的开发同步过来

```

### 10.2 公司忘记提交代码情况

```python

# 忽然有一天,在公司开发了代码,没有提交到远程仓库

# 回家就没法拉取最新公司开发的代码,只能基于远程仓库最新代码继续开发其他功能(跟公司开发的功能不一样)

# 在家中开发完成提交到远程

# 第二条天到公司,拉取远程最新代码(可能有冲突)

```

## 11 Git标签管理

```python

# 1 打tag

git tag -a "v1.0" -m "new tag v1.0"

# 2 推送tag到远程

git push origin v1.0

# 3 可以看到远程有tag了

# 4 基于其他位置打log

git reflog # 查看日志id

# 5 打tag

git tag -a "v1.1" id号 -m 'test'

# 6 推送tag到远程

git push origin v1.1

```

## 12 为开源项目贡献代码

```python

# 第一步:fork开源代码,fork后,在你的个人仓库里就可以看到这个开源代码了(相当于copy了一份)

# 第二步:在自己仓库进行修改

修改代码,提交暂存,提交到版本库,提交到自己gitee

# 第三步:给开源作者提交pr

# 第四步:开源软件作者就会收到pr,他选择是否合并,合并后,你就成了开源软件开发者

```

![image-20210924011328551](https://tva1.sinaimg.cn/large/008i3skNgy1gur2bzmed2j61lq0u043002.jpg)

## 13 变基操作(rebase)

**让提交记录变得更加简洁**

### 13.1 第一,多个记录整合成一个记录

![未命名文件 (5)](https://tva1.sinaimg.cn/large/008i3skNgy1gur3uhyglyj60np08eaag02.jpg)

```python

git branch lqz  # 创建分支lqz

git checkout lqz # 切换到分支lqz

vi lqz.txt       

git add .

git commit -m '增加lqz.txt' # 新增lqz.txt 并提交

vi lqz1.txt

git add .

git commit -m '增加lqz1.txt' # 新增lqz1.txt 并提交

vi lqz2.txt

git add .

git commit -m '增加lqz2.txt' # 新增lqz2.txt 并提交

git log   # 查看版本日志

# 指定合并从当前版本开始往前的哪个版本(不包含)

git rebase -i 8fa035cd6805e8b35ccb9ceee9a9710c9b819b3c

# 把第二行开始,改为s

# 加入注释,合并后的注释

git log # 只能看到合并后的注释了,多次更改变成了一次

# 注意:已经提交到远程仓库的版本,不要再使用rebase,只合并本地版本提交的几率

```

### 13.2第二,解决分支合并分叉问题

![未命名文件 (6)](https://tva1.sinaimg.cn/large/008i3skNgy1gur4jas2zoj61150d0dgj02.jpg)

```python

#### 正常merge合并

git branch dev

git checkout dev

vi dev.txt

git add .

git commit -m 'dev增加dev.txt'

git checkout master

vi master.txt

git add .

git commit -m 'master增加master.txt'

# 使用merge合并

git merge dev # 写入注释合并

# 图形化查看版本情况

git log --graph

##### 使用rebase合并

git branch -d dev # 删除dev分支

git branch dev

git checkout dev # 新建,切换到dev分支

vi dev1.txt

git add . 

git commit -m 'dev 增加dev1.txt' # 新建dev1.txt 并提交到版本库

git checkout master

vi master1.txt

git add .

git commit -m 'master增加master1.txt' # 切换到master,新建master1.txt,并提交到版本库

git checkout dev

git rebase master  # 切换到dev分支,完成变基

git checkout master

git merge dev     # 切换到master,完成合并

git log --graph   # 查看,变成了一条线

```

![image-20210924023612523](https://tva1.sinaimg.cn/large/008i3skNgy1gur4q25eflj617e0kw41r02.jpg)

#### rebase合并出冲突情况解决

```python

git branch -d dev # 删除dev分支

git branch dev

git checkout dev # 新建,切换到dev分支

vi lqz.txt       # 在内部增加一行话

git add . 

git commit -m 'dev 增加lqz.txt' # 新建lqz.txt 并提交到版本库

git checkout master

vi lqz.txt

git add .      # 在内部也增加一行话

git commit -m 'master增加lqz.txt' # 切换到master,新建lqz.txt,并提交到版本库

git checkout dev

git rebase master  # 切换到dev分支,完成变基,出现冲突

# 解决冲突

vi lqz.txt  # 把冲突解决掉

# 查看状态

git status # git rebase正在进行状态

# 继续往下走

git add .

git rebase --continue

git checkout master

git merge dev     # 切换到master,完成合并

git log --graph   # 查看,变成了一条线

git rebase --continue

```

### 13.3 第三

```python

git branch -d dev

git branch dev

git checkout dev # 删掉dev,重新创建,并切换到dev分支

git push origin dev # 把本地dev同步到远程

vi gs.txt

git add .

git commit -m '公司写了代码,提交到本地'  # 忘了提交到远程仓库

# 回家后,继续开发,从远程拉下来

mkdir pr

cd pr

git clone https://gitee.com/liuqingzheng/app01.git  # 把代码克隆下来

cd app01

git checkout dev   # 切换到dev分支,此时是没有gs.txt的

vi j.txt           # 在家继续开发

git add .

git commit -m '家里写了代码'  

git push origin dev      # 家里写的代码提交到远程仓库

# 第二天来到公司,拉取代码继续开发,如果直接拉取,会分叉

# 不使用git pull 拉取代码,会分叉

# 先 git fetch 拉取

git fetch origin dev  # 先拿下来,自定合并代码,使用merge合并会分叉

# 使用rebase合并

git rebase origin/dev

'''

由原来的 git pull origin dev

变成

git fetch origin dev

git rebase origin/dev

'''

```

![image-20210924030355748](https://tva1.sinaimg.cn/large/008i3skNgy1gur5ix3r35j61160n677j02.jpg)

## 

## 14 git pull 和git fetch

```python

1. 相同点

首先在作用上他们的功能是大致相同的,都是起到了更新代码的作用。

2. 不同点

git pull 类似于 git fetch+git merge

```


跟老刘学python

0基础python教程 Docker部署gitlab(避坑版)

学python的时候都绕不过去docker的运用,现在和老刘一起来学docker等到你就业的时候,就知道这一块在IT市场上有多么的重要了,话不多说,干货走起。

## 1 下载docker

```python

# 安装依赖

yum install -y yum-utils device-mapper-persistent-data lvm2

# 设置yum源

yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

# 安装docker...

学python的时候都绕不过去docker的运用,现在和老刘一起来学docker等到你就业的时候,就知道这一块在IT市场上有多么的重要了,话不多说,干货走起。

## 1 下载docker

```python

# 安装依赖

yum install -y yum-utils device-mapper-persistent-data lvm2

# 设置yum源

yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

# 安装docker

yum install -y docker-ce

# 设置开机启动

systemctl enable docker

# 启动 Docker

systemctl start docker

# 查看版本

docker version

```

## 2 下载gitlab镜像

```

docker pull gitlab/gitlab-ce:latest

```

## 3 运行

```python

mkdir gitlab gitlab/etc gitlab/log gitlab/opt  

docker run -id -p 3000:80 -p 9922:22 -v /root/gitlab/etc:/etc/gitlab  -v /root/gitlab/log:/var/log/gitlab -v /root/gitlab/opt:/var/opt/gitlab --restart always --privileged=true --name gitlab gitlab/gitlab-ce


'''

命令解释:

-i  以交互模式运行容器,通常与 -t 同时使用命令解释:

-d  后台运行容器,并返回容器ID

-p 3000:80  将容器内80端口映射至宿主机9980端口,这是访问gitlab的端口

-p 9922:22  将容器内22端口映射至宿主机9922端口,这是访问ssh的端口

-v ./gitlab/etc:/etc/gitlab  将容器/etc/gitlab目录挂载到宿主机./gitlab/etc目录下,若宿主机内此目录不存在将会自动创建,其他两个挂载同这个一样

--restart always  容器自启动

--privileged=true  让容器获取宿主机root权限

--name gitlab-test  设置容器名称为gitlab

gitlab/gitlab-ce  镜像的名称,这里也可以写镜像ID

'''

```

## 4 进入容器内部修改

```python

docker exec -it gitlab /bin/bash

# 修改gitlab.rb

vi /etc/gitlab/gitlab.rb

## 加入如下

# gitlab访问地址,可以写域名。如果端口不写的话默认为80端口

external_url 'http://101.133.225.166'

# ssh主机ip

gitlab_rails['gitlab_ssh_host'] = '101.133.225.166'

# ssh连接端口

gitlab_rails['gitlab_shell_ssh_port'] = 9922

# 让配置生效

gitlab-ctl reconfigure

### 注意不要重启,/etc/gitlab/gitlab.rb文件的配置会映射到gitlab.yml这个文件,由于咱们在docker中运行,在gitlab上生成的http地址应该是http://101.133.225.166:3000,所以,要修改下面文件

# 修改http和ssh配置

vi /opt/gitlab/embedded/service/gitlab-rails/config/gitlab.yml

  gitlab:

    host: 101.133.225.166

    port: 3000 # 这里改为3000

    https: false

# 重启

gitlab-ctl restart

# 退出容器

exit

```

![image-20210923172243424](https://tva1.sinaimg.cn/large/008i3skNgy1guqoq7fbp4j61bs070dhb02.jpg)

## 5 在浏览器里访问

```python

# 机器配置要大于4g,否则很容易启动不了,报502

http://101.133.225.166:3000/

# 第一次访问,会让修改root密码

# 修改后以root用户登录即可

```

![image-20210406230709530](https://tva1.sinaimg.cn/large/008eGmZEgy1gpafc56s9yj31fj0u0n16.jpg)

## 6 修改root密码(如果忘记请修改)

```python

# 进入容器内部

docker exec -it gitlab /bin/bash

# 进入控制台

gitlab-rails console -e production

# 查询id为1的用户,id为1的用户是超级管理员

user = User.where(id:1).first

# 修改密码为lqz123456

user.password='lqz123456'

# 保存

user.save!

# 退出

exit

```

## 7 创建项目

![image-20210923173230742](https://tva1.sinaimg.cn/large/008i3skNgy1guqp0e9zf0j61c50u077a02.jpg)

![image-20210923173351840](https://tva1.sinaimg.cn/large/008i3skNgy1guqpdewug8j610c0u0tca02.jpg)

**后续操作就是git基本操作**


跟老刘学python

0基础python教程 Python项目高并发异步部署实战+压测

接着上一章,往下学习,本章主要讲解Python项目高并发异步部署实战+压测,学习的小伙伴千万不能错过本课,本课是实践课非常的重要哦~~~

## 1 前言

由于Python有把大锁GIL,会将多个线程在同一时刻,只能有一个线程执行,变成'串行',所以一个多线程python进程,并不能充分使用多核CPU资源,所以对于Python进程,可采用多进程部署方式比较有利于充分利用多核的CPU资源,而uWSGI服务器就是这么一个东西,可以以多进程方式执行WSGI app,其工作模式为 1 master进程 + N worker进程+m个线程(N*m线程),主进程负责接收客户端请求,然后将请求转...

接着上一章,往下学习,本章主要讲解Python项目高并发异步部署实战+压测,学习的小伙伴千万不能错过本课,本课是实践课非常的重要哦~~~

## 1 前言

由于Python有把大锁GIL,会将多个线程在同一时刻,只能有一个线程执行,变成'串行',所以一个多线程python进程,并不能充分使用多核CPU资源,所以对于Python进程,可采用多进程部署方式比较有利于充分利用多核的CPU资源,而uWSGI服务器就是这么一个东西,可以以多进程方式执行WSGI app,其工作模式为 1 master进程 + N worker进程+m个线程(N*m线程),主进程负责接收客户端请求,然后将请求转发给worker进程,因此最终是worker进程负责处理客户端请求,这样很方便的将WSGI app以多进程方式进行部署**此方式是企业常用部署方式**

**但是存在一个问题**

客户端向uwsgi的一个master发起一个HTTP请求,master分发给不同的worker进程,worker进程拉起线程处理请求,进入web框架,直到该请求处理完,这个线程才能处理其他请求,所以wsgi app是同步的。假如一个请求处理花费时间比较久,客户端请求数量又比较多的情况下,所有的线程都会被占满,所以就处理不了更多的请求(最大连接数取决于进程N*线程M)

**我们的处理方案**

1)增大N,即worker的数量:在增加进程的数量的时候,进程是要消耗内存的,并且如果进程数量太多的情况下(并且进程均处于活跃状态),进程间的切换会消耗系统资源的,所以N并不是越大越好。一般情况下,可能将进程数目设置为CPU数量的2倍

2)增大m,即worker的线程数量:线程创建也是有限度的,由于线程栈是要消耗内存的,线程数量太多也不行

于是我们想,一条线程能不能同时处理多个请求呢?可以使用IO多路复用的模型

**于是,gevent登场了**

gevent是用户态的'线程',也就是协程,单线程下实现并发

gevent的好处就是无需等待I/O,当发生I/O调用是,gevent会主动切换到另一gevent进行运行,这样可以充分利用CPU资源

同时gevent通过monkey patch(猴子补丁)替换掉了标准库中阻塞的模块

## 2 以flask项目为例,使用uwsgi+gevent部署高并发实战

### 2.1 新建flask项目 (s1.py)

```python

from flask import Flask

import time

app = Flask(__name__)

@app.route('/')

def hello_world():

    time.sleep(1) # 引入io操作

    return 'Hello World!'

if __name__ == '__main__':

    app.run()

```

## 2.2 新建uwsgi.py

```python

[uwsgi]

http = 0.0.0.0:5000

chdir = /root/20210318/

wsgi-file = /root/20210318/s1.py

processes = 2

threads = 8

buffer-size = 32768

master = true

pidfile = uwsgi.pid

daemonize = uwsgi.log

callable = app

---------------------------

[uwsgi]

http = 0.0.0.0:5000 # 监听地址和端口

chdir = /root/test/ # 项目路径

wsgi-file = /root/test/s1.py # py文件路径

processes = 1 # 进程数

threads = 1   # 线程数

buffer-size = 32768 # 缓存大小

master = true       #允许主进程存在

pidfile = uwsgi.pid # pid位置

daemonize = uwsgi.log#日志文件

callable = app   #flask中flask对象的名字,flask部署需要配置它

-----------uwsgi其他参数------------------

socket : 地址和端口号,例如:socket = 127.0.0.1:50000

processes : 开启的进程数量

workers : 开启的进程数量,等同于processes(官网的说法是spawn the specified number of  workers / processes)

chdir : 指定运行目录,项目根路径(chdir to specified directory before apps loading)

wsgi-file : 载入wsgi-file,wsgi文件,flask就是app.py(load .wsgi file)

stats : 在指定的地址上,开启状态服务(enable the stats server on the specified address)

threads : 运行线程。(run each worker in prethreaded mode with the specified number of threads)

master : 允许主进程存在(enable master process)

daemonize : 使进程在后台运行,并将日志打到指定的日志文件或者udp服务器(daemonize uWSGI)。实际上最常用的,还是把运行记录输出到一个本地文件上。

log-maxsize :以固定的文件大小(单位KB),切割日志文件。 例如:log-maxsize = 50000000  就是50M一个日志文件。

pidfile : 指定pid文件的位置,记录主进程的pid号。

vacuum : 当服务器退出的时候自动清理环境,删除unix socket文件和pid文件(try to remove all of the generated file/sockets)

disable-logging : 不记录请求信息的日志。只记录错误以及uWSGI内部消息到日志中。如果不开启这项,那么你的日志中会大量出现这种记录:

log-maxsize : 日志大小,当大于这个大小会进行切分 (Byte)

log-truncate : 当启动时切分日志

buffer-size : 比如前端(客户端)向后端(服务器)发了一个请求,请求的大小是5M,那么buffer-size的大小就得大于1024*5,不然就报错了

callable :app  #变量app 与 App.py文件中的app = Flask(__name__)对应

```

## 2.3 在centos7.5机器上测试

>第一步:安装python3.6环境(略)

>

>第二步:安装uwsgi (pip3 install uwsgi)

>

>    -uwsgi在1.4版本以上,就支持gevent(官方介绍:https://uwsgi-docs-zh.readthedocs.io/zh_CN/latest/Gevent.html)

>

>第三步:安装flask    (pip3 install flask)

>

>第四步:安装gevent   (pip3 install gevent)

## 2.4 首先不使用gevent启动uwsgi

>uwsgi uwsgi.ini

## 2.5 使用gevent启动uwsgi

>

>uwsgi --gevent 100 --gevent-monkey-patch uwsgi.ini

>

## 2.6 压测两个接口

>ab -n 10 -c 5 http://101.133.225.166:5000/

>

>不使用gevent跑,可以看到 requests per second (每秒请求数为0.99)

>ab -n 10 -c 5 http://101.133.225.166:5000/

>

>使用gevent跑,可以看到 requests per second (每秒请求数为3.28)


跟老刘学python

0基础python教程 docker-compose部署Yapi

很多的同学对于自己没有基础又想要学习python而头疼,不知道该从哪里学习开始好,也没有固定的规划,今天老刘带你0基础学python,系统的进行学习和实践,让你没有基础也能进入IT行业。

## 1 安装docker

```python

sudo yum install -y yum-utils device-mapper-persistent-data lvm2

sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

sudo yum install...

很多的同学对于自己没有基础又想要学习python而头疼,不知道该从哪里学习开始好,也没有固定的规划,今天老刘带你0基础学python,系统的进行学习和实践,让你没有基础也能进入IT行业。

## 1 安装docker

```python

sudo yum install -y yum-utils device-mapper-persistent-data lvm2

sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

sudo yum install docker-ce

systemctl start docker

```

## 2 安装docker-compose

```python

curl -L https://get.daocloud.io/docker/compose/releases/download/1.29.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

chmod +x /usr/local/bin/docker-compose

```

## 3 新建docker-compose.yml

>vim docker-compose.yml

```python

version: '3'

services:

  yapi-web:

    image: liuqingzheng/yapi:latest

    container_name: yapi-web

    ports:

      - 3000:3000

    environment:

      - YAPI_ADMIN_ACCOUNT=306334678@qq.com

      - YAPI_ADMIN_PASSWORD=admin

      - YAPI_CLOSE_REGISTER=true

      - YAPI_DB_SERVERNAME=yapi-mongo

      - YAPI_DB_PORT=27017

      - YAPI_DB_DATABASE=yapi

      - YAPI_MAIL_ENABLE=false

      - YAPI_LDAP_LOGIN_ENABLE=false

      - YAPI_PLUGINS=[]

    depends_on:

      - yapi-mongo

    links:

      - yapi-mongo

    restart: unless-stopped

  yapi-mongo:

    image: mongo:latest

    container_name: yapi-mongo

    volumes:

      - ./data/db:/data/db

    expose:

      - 27017

    restart: unless-stopped

```

## 4 启动

```python

docker-compose up -d # 启动

docker-compose stop  # 停止

docker-compose rm    # 删除

```

## 5 访问

```python

http://127.0.0.1:3000/

输入邮箱:306334678@qq.com

输入密码:admin

```


yangli-1128

Installing Docker on CentOS 6

⚠警告:在CentOS 6使用docker 可能会造成系统 宕机

1.修改/etc/yum.repos.d/CentOS-Base.repo

内容为:

[centos-office]

name=centos-office

failovermethod=priority

baseurl=https://vault.centos.org/6.10/os/x86_64/

gpgcheck=1

gpgkey=https://vault.centos.org/6.10/os/x86_64/RPM-GPG-KEY-CentOS-6

2.安装docker 1.7.1

yum install...

⚠警告:在CentOS 6使用docker 可能会造成系统 宕机

1.修改/etc/yum.repos.d/CentOS-Base.repo

内容为:

[centos-office]

name=centos-office

failovermethod=priority

baseurl=https://vault.centos.org/6.10/os/x86_64/

gpgcheck=1

gpgkey=https://vault.centos.org/6.10/os/x86_64/RPM-GPG-KEY-CentOS-6

2.安装docker 1.7.1

yum install -y https://get.docker.com/rpm/1.7.1/centos-6/RPMS/x86_64/docker-engine-1.7.1-1.el6.x86_64.rpm

可能会提示某些库版本过低,可以更新版本

yum update -y device-mapper-libs

yum install nss

3.启动docker

service docker restart

================================

在安装过程中遇到的问题

1.开始安装的是1.7.0,会提示错误,在网上搜索后使用1.7.1

2.安装的时候提示 /usr/bin 无法写入。

使用lsattr /usr/,发现/usr/bin有一个 i 的属性,取消i属性(chattr -i /usr/bin)

本次安装的服务器中毒导致/usr/bin文件夹无法写入。网上搜索安装docker 多数为1.7.0的,导致了一些错误。

----------------------------------

⚠警告:在CentOS 6使用docker 可能会造成系统 宕机

-----------------------------------

LOFTER

让兴趣,更有趣

简单随性的记录
丰富多彩的内容
让生活更加充实

下载移动端
关注最新消息