上药三品,神与气精

曾因酒醉鞭名马 生怕情多累美人


  • 首页

  • 关于

  • 分类

  • 标签

  • 归档

  • 搜索

关注最后一步-部署

发表于 2019-04-01 | 分类于 web | 阅读次数:
字数统计: 716 | 阅读时长 ≈ 2

gunicorn

1.Gunicorn设计

  Gunicorn 是一个 master 进程,spawn 出数个工作进程的 web 服务器。master 进程控制工作进程的产生与消亡,工作进程只需要接受请求并且处理。这样分离的方式使得 reload 代码非常方便,也很容易增加或减少工作进程。 工作进程这块作者给了很大的扩展余地,它可以支持不同的IO方式,如 Gevent,Sync 同步进程,Asyc 异步进程,Eventlet 等等。master 跟 worker 进程完全分离,使得 Gunicorn 实质上就是一个控制进程的服务。

2.Gunicorn源码结构

  从 Application.run() 开始,首先初始化配置,从文件读取,终端读取等等方式完成 configurate。然后启动 Arbiter,Arbiter 是实质上的 master 进程的核心,它首先从配置类中读取并设置,然后初始化信号处理函数,建立 socket。然后就是开始 spawn 工作进程,根据配置的工作进程数进行 spawn。然后就进入了轮询状态,收到信号,处理信号然后继续。这里唤醒进程的方式是建立一个 PIPE,通过信号处理函数往 pipe 里 write,然后 master 从 select.select() 中唤醒。

工作进程在 spawn 后,开始初始化,然后同样对信号进行处理,并且开始轮询,处理 HTTP 请求,调用 WSGI 的应用端,得到 resopnse 返回。然后继续。

Sync 同步进程的好处在于每个 request 都是分离的,每个 request 失败都不会影响其他 request,但这样导致了性能上的瓶颈。

没有对错,找个框架入门好了~

flask 上手快,插件多,但是随着项目的深入,慢慢就是变成一个 django,绝对的
django 一上来就是大而全,但胜在什么都有,什么都不用自己折腾

tornado 这货从一出生就开始用到现在,没有啥好也没啥不好,就是用习惯了。flask 的上手快是以各种插件为代价的,模板你要去找 jinja 吧? orm 要找 sqlachemy 吧?这些都需要你自己去熟悉一下

而且,各种用 flask 和 django 的同学可能忽略了一个基本是事实就是,如果你有工作需要深入到源代码的话,那么 tornado 是一个极好的参考。django 的代码体系复杂而且庞大我就不说了,看 flask 的代码底层还要考虑 Werkzeug,其基于全局变量的 context 处理起来其实也不容易的。

顺便的,部署 tornado 的项目可以少拖一个 gunicorn 或者 uwsgi 之如此类,少很多坑

上面那些提及到性能的同学,完全没有必要进行对比。在 pypy/aiohttp/uvloop 的加持下,不是我非要针对谁,你们说的性能都是垃圾。

leetcode完美数

发表于 2019-03-31 | 阅读次数:
字数统计: 71 | 阅读时长 ≈ 1

完美数

1
2
3
4
5
6
7
8
9
10
11
12
13

class Solution {
public:
bool checkPerfectNumber(int num) {
int sum = 1;
for (int i = 2; i * i <= num; ++i) {
if (num % i == 0) {
sum += i + (num / i == i ? 0 : num / i);
}
}
return num != 1 && sum == num;
}
};
1
2
3
4
5
6
7

class Solution {
public:
bool checkPerfectNumber(int num) {
return num == 6 || num == 28 || num == 496 || num == 8128 || num == 33550336;
}
};

2019-go-28

发表于 2019-03-28 | 分类于 golang | 阅读次数:
字数统计: 158 | 阅读时长 ≈ 1

go的

协程和线程都可以实现程序的并发执行

通过channel来进行协程之间的通信

一个包中可以包含多个init函数

程序编译的时候 先执行导入包init的函数 再执行本包内的init函数


几个缺陷

  • 不支持函数式编程 go的泛型会給项目带来不必要的复杂性
  • 通道/并行切片处理
  • 垃圾回收器 以低延迟为最高优先级
  • 错误处理

如果完成一个api 或者完成一个需要大量磁盘/网络调用的任务 go是首选!!!

2019-go-27

发表于 2019-03-28 | 分类于 golang | 阅读次数:
字数统计: 115 | 阅读时长 ≈ 1

beego 模块化设计之 config

解析文件的库,它的设计思路来自于 database/sql,目前支持解析的文件格式有 ini、json、xml、yaml

初始化解析器

iniconf, err := NewConfig("ini", "testini.conf")
if err != nil {
    t.Fatal(err)
}

iniconf.String("appname")

解析器对象支持的函数有如下:

  • Set(key, val string) error
  • String(key string) string
  • Int(key string) (int, error)
  • Int64(key string) (int64, error)
  • Bool(key string) (bool, error)
  • Float(key string) (float64, error)
  • DIY(key string) (interface{}, error)

2019-go-26

发表于 2019-03-28 | 分类于 golang | 阅读次数:
字数统计: 938 | 阅读时长 ≈ 4

beego 模块化设计之 toolbox

健康检查

监控检查是用于当你应用于产品环境中进程,检查当前的状态是否正常,

1
2
3
4
5
6
7
8
9
10
type DatabaseCheck struct {
}

func (dc *DatabaseCheck) Check() error {
if dc.isConnected() {
return nil
} else {
return errors.New("can't connect database")
}
}
toolbox.AddHealthCheck("database",&DatabaseCheck{})
curl http://beego.me:8088/healthcheck

性能调试、访问统计、计划任务。

对于运行中的进程的性能监控是我们进行程序调优和查找问题的最佳方法,例如 GC、goroutine 等基础信息。profile 提供了方便的入口方便用户来调试程序,他主要是通过入口函数 ProcessInput 来进行处理各类请求,主要包括以下几种调试:

lookup goroutine/heap/threadcreate/block/

start cpuprof

开始记录 cpuprof 信息,生产一个文件 cpu-pid.pprof,开始记录当前进程的 CPU 处理信息

stop cpuprof

关闭记录信息

get memprof

开启记录 memprof,生产一个文件 mem-pid.memprof

gc summary

查看 GC 信息

toolbox.StatisticsMap.AddStatistics("POST", "/api/user", "&admin.user", time.Duration(2000))
toolbox.StatisticsMap.AddStatistics("POST", "/api/user", "&admin.user", time.Duration(120000))
toolbox.StatisticsMap.AddStatistics("GET", "/api/user", "&admin.user", time.Duration(13000))
toolbox.StatisticsMap.AddStatistics("POST", "/api/admin", "&admin.user", time.Duration(14000))
toolbox.StatisticsMap.AddStatistics("POST", "/api/user/astaxie", "&admin.user", time.Duration(12000))
toolbox.StatisticsMap.AddStatistics("POST", "/api/user/xiemengjun", "&admin.user", time.Duration(13000))
toolbox.StatisticsMap.AddStatistics("DELETE", "/api/user", "&admin.user", time.Duration(1400))

toolbox.StatisticsMap.GetMap(os.Stdout)

玩过 linux 的用户都知道有一个计划任务的工具 crontab,我们经常利用该工具来定时的做一些任务,但是有些时候我们的进程内也希望定时的来处理一些事情,例如定时的汇报当前进程的内存信息,goroutine 信息等。或者定时的进行手工触发 GC,或者定时的清理一些日志数据等,所以实现了秒级别的定时任务,首先让我们看看如何使用:

tk1 := toolbox.NewTask("tk1", "0 12 * * * *", func() error { fmt.Println("tk1"); return nil })
err := tk.Run()
if err != nil {
    t.Fatal(err)
}
toolbox.AddTask("tk1", tk1)
toolbox.StartTask()
defer toolbox.StopTask()

字段的详细说明

 //前6个字段分别表示:
//       秒钟:0-59
//       分钟:0-59
//       小时:1-23
//       日期:1-31
//       月份:1-12
//       星期:0-6(0 表示周日)

//还可以用一些特殊符号:
//       *: 表示任何时刻
//       ,: 表示分割,如第三段里:2,4,表示 2 点和 4 点执行
//      -:表示一个段,如第三端里: 1-5,就表示 1 到 5 点
//       /n : 表示每个n的单位执行一次,如第三段里,*/1, 就表示每隔 1 个小时执行一次命令。也可以写成1-23/1.
/////////////////////////////////////////////////////////
//  0/30 * * * * *                        每 30 秒 执行
//  0 43 21 * * *                         21:43 执行
//  0 15 05 * * *                        05:15 执行
//  0 0 17 * * *                          17:00 执行
//  0 0 17 * * 1                          每周一的 17:00 执行
//  0 0,10 17 * * 0,2,3                   每周日,周二,周三的 17:00和 17:10 执行
//  0 0-10 17 1 * *                       毎月1日从 17:00 到 7:10 毎隔 1 分钟 执行
//  0 0 0 1,15 * 1                        毎月1日和 15 日和 一日的 0:00 执行
//  0 42 4 1 * *                         毎月1日的 4:42 分 执行
//  0 0 21 * * 1-6                       周一到周六 21:00 执行
//  0 0,10,20,30,40,50 * * * *            每隔 10 分 执行
//  0 */10 * * * *                     每隔 10 分 执行
//  0 * 1 * * *                       从 1:0 到 1:59 每隔 1 分钟 执行
//  0 0 1 * * *                       1:00 执行
//  0 0 */1 * * *                      毎时 0 分 每隔 1 小时 执行
//  0 0 * * * *                       毎时 0 分 每隔 1 小时 执行
//  0 2 8-20/3 * * *                   8:02,11:02,14:02,17:02,20:02 执行
//  0 30 5 1,15 * *                    1 日 和 15 日的 5:30 执行
1…232425…109
John Cheung

John Cheung

improve your python skills

543 日志
33 分类
45 标签
RSS
GitHub Email
© 2020 John Cheung
本站访客数:
|
主题 — NexT.Pisces v5.1.4
博客全站共226.3k字