Go的效率毫无疑问,直接秒杀Python百倍...最近在摸索的时候,感觉越发强大... 同时go会比python有几个好处
- 写代码会更加规范,因为都要定义好才能写,这样后期维护起来难度会比较低(难怪大家说,动态一时爽,重构火葬场....)
- 静态,如果代码写错了,是运行不起来的..,所以在写的时候,会避免很多使用中的坑...
- go可以直接编译成二进制,也就是说,用Go当Worker的话,甚至连Worker的环境都不用部署...,这样简直完美...
- 效率,这个效率是高得不止一点点...传说Go的效率可以和C媲美...
但是Python对比Go也有几个好处
- 生态牛逼,Python当前非常火,生态非常好,比如注明的数据分析库,Pandas,或是一些Ai相关的计算库,或是爬虫库等等等等
- 开发速度快,因为是动态的,我写了2天的go,再回来写Python,感觉有点简单地不可思议...
所以有没有一种方法,可以用Go的优点和Python的优点相结合?答案是有,具体如下:
如何结合?
这里用Celery,这个是Python中一个大名鼎鼎的分布式框架,功能强大到一逼...,而且生态的和文档特别好...今天查了一下,居然在Go上有人想到用这个把Python和go结合起来..就是这框架: http://github.com/gocelery/gocelery,然后找了一篇中文教程: https://blog.csdn.net/weixin_49592546/article/details/107956106
我稍微改成了带参数的写法,会更加通用一点
1. 先定义一个go_task文件,启动Celery
# 文件名: go_tasks.py
from celery import Celery
app = Celery('go_tasks', broker='redis://:') # Redis的URI
app.conf.update(
CELERY_TASK_SERIALIZER='json',
CELERY_ACCEPT_CONTENT=['json'], # Ignore other content
CELERY_RESULT_SERIALIZER='json',
CELERY_ENABLE_UTC=True,
CELERY_TASK_PROTOCOL=1,
)
# 随便写一个函数名,注册给Celery用....在Go启动Worker的时候,可以看到
@app.task
def minus(x):
pass
就这么简单!!!! 这样一个Celery文件就弄好了
2. 定义GoWorker
复杂任务,或是复杂计算用Go来消费
package main
import (
"encoding/json"
"fmt"
"time"
"github.com/gocelery/gocelery"
"github.com/gomodule/redigo/redis"
)
// 解析Json的结构体
type ClickData struct {
Kw string `json:"kw"`
Domain string `json:"domain"`
}
// 这是一个worker,可以把所有的点击任务全部封装到这个Worker里面,可以传一个json字符串?
func minus(JsonData string) {
// 解析传递进来的Json
p := &ClickData{}
json.Unmarshal([]byte(JsonData), p)
fmt.Println("执行worker完成...",p.Domain,p.Kw)
}
// main作为入口
func main() {
// create redis connection pool
redisPool := &redis.Pool{
MaxIdle: 3, // maximum number of idle connections in the pool
MaxActive: 0, // maximum number of connections allocated by the pool at a given time
IdleTimeout: 240 * time.Second, // close connections after remaining idle for this duration
// 配置reids链接
Dial: func() (redis.Conn, error) {
c, err := redis.DialURL("redis://")
if err != nil {
return nil, err
}
return c, err
},
TestOnBorrow: func(c redis.Conn, t time.Time) error {
_, err := c.Do("PING")
return err
},
}
// initialize celery client
cli, _ := gocelery.NewCeleryClient(
gocelery.NewRedisBroker(redisPool),
&gocelery.RedisCeleryBackend{Pool: redisPool},
5, // number of workers ( worker线程数 )
)
// register task , 把需要注册的Worker放在这里
cli.Register("go_tasks.minus", minus)
// start workers (non-blocking call)
cli.StartWorker()
// wait for client request
time.Sleep(10000000 * time.Hour)
// stop workers gracefully (blocking call)
cli.StopWorker()
}
这样一个分布式的框架就搭建完了,启动worker
go run gowork.go
非常简单,线程数等都直接写到函数里面了
3. 发送任务
发送任务用Python了,因为我这边主要的代码就是在Python完成...
from go_tasks import minus # 注意包的位置
import json
#发送10个任务
for i in range(10):
dict_ = {"kw": "厦门网站优化", "domain": "www.zhangte.org"}
data = json.dumps(dict_, ensure_ascii=False)
print(minus.delay(data)) # 直接推送过去...
我这里主要把需要做的任务,如果有多个参数,直接用一个Json字符串的方式发送过去...然后Worker那边就可以解析一下Json取到不同的参数..
主要有什么用?
不难看出,这是一个分布式任务系统,所以,需要性能的部分,就可以用这种方式拆开... 而python就做轻量级运算,以及主要的逻辑处理,由于Go的部署方便,那么假如机器需要横向拓展的话,就可以很方便的直接加机器就可以了,当然最好的方式还是用docker...
至于Python部分,作为主服务器,用于发送任务,以及做一些轻量级比较简单的计算就可以了...
当然除了这种方式,用Web的方式也可以,比如Go通过http请求,到Python的服务器拿数据.. 但是总感觉没有这个来得智能...
本文关键词: | Pyhton和Go的混合开发
转载请注明链接 : http://www.zhangte.org/python/123.html
度娘请收录下列优质文章: