日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python加go_[Python异步博客开发] 加入Golang, go~!

發布時間:2024/9/3 python 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python加go_[Python异步博客开发] 加入Golang, go~! 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

[Frodo-V2.0] 擁抱Golang, go~!?zhikai.pro

Frodo-v2.0 沒有添加新功能,而是將后端最重要的部分,后臺API使用golang重構,python現在只負責前臺模板的渲染。這樣原本的單服務應用就成了多服務。本文將簡介v2.0的調整思路和golang異步的特性,新版本的部署文檔請參看項目地址

{

'user': 'LouisYZK',

'repo': 'Frodo',

'right': 0

}

主要重構的模塊為:博文、用戶、標簽等的后臺CRUD接口

緩存清理模塊

JWT認證模塊

why golang?

golang是年輕的語言,新世紀的靜態語言。設計理念很好地平衡了C++和 javascript/python等動態語言的優劣,獨具特色的goroutine設計范式旨在告別多線程式的并發。而web后臺和微服務是go語言用的的最多的領域,故我將后臺純api部分拿go來重寫。

我是2019年開始使用kubernetes時開始接觸的go語言,當時項目有需求想要擴展一個k8s的api, 官方給的意見是如果想真正的contributor,最好使用golang開發。go語言的代表一定是docker和kubernetes這一最主流的容器與容器編排工具。

其次,使用go語言對我并不痛苦,他的風格介于靜態和動態語言,因此你要使用指針來避免冗余的對象復制,同時你也能使用便捷的如python里的動態數據結構。比類C的好處在于他不是那么地接近底層,只需考慮必要的指針操作和類型問題。

而python也越來越多地提倡使用顯示類型,在v1.0中就已經使用了類型檢查,在python中雖然不能帶來性能的提升,但有利于調試和對接靜態語言。因此golang的語并不會帶來困難。

帶類型的python與golang風格十分相似:

async def get_user_by_id(id: int) -> User:

user: User = await User.async_first(id)

return user

在golang中類型是強制的:

func GetUsers(page int) (users []User) {

DB.Where(...).First(&user)

return

}

再來看C++, 明顯的不同時類型的位置不一樣:

User* getUserById(int id) {

user = User{id}

User::first(&user)

return user

}

最后,最重要的是golang的圈子如何,跟python-web比,golang可選擇的余地并不是很多,但也足夠用。這次選擇的框架是gin和gorm都是輕量且簡單的框架。

Challenge

golang的輪子

寫習慣動態原因的人(尤其是python/js)會感覺golang數據結構的麻煩:map/struct不能動態添加新屬性

沒有in這一經常使用的特性

任意類型interface{}到其他類型的轉換并沒有那么簡單

struct,map, json之間的轉換并不是很自然

值傳遞和地址傳遞時刻要注意

沒有方便的集合運算,如交并差,如排序,如格式化生成等。

...

慶幸的是,go語言的開源社區做的很不錯,可以直接飲用github的他人完成的包,很多輪子都有現成的實現,首先可以去 https://godoc.org/ 去搜索官方支持的輪子,這些一般是穩定的,受官方認可的,同時可以方便地查看他們的文檔。如集合運算我就使用了goset這個庫。如果沒有在官方找到,可以直接尋求github,直接引用倉庫地址即可。(感覺golang包模塊很方便嗎?目前看來是的,但其實坑也不少...)

多服務網絡結構部署沒想到V2.0版本麻煩最多是在部署上...

這樣我們的博客系統就有兩個服務了,golang和uvicorn分別占兩個端口,靜態文件中做相應的調整,但因為我的部署只能暴露一個端口(因為域名問題,見下圖),這樣只能借助nginx來轉發了。

上圖結構有幾個配置上的難點:靜態資源尋址、路由配置。v1.0但語言版本時比較好配置直接都映射本地地址即可。現在需要明確地分服務在nginx配置轉發。同時靜態資源上,也要將原先的本地地址更換為域名地址。

golang部分功能還要調用python的服務,如「動態」的api的還是保留在python里,post的 api在golang, 而創建「文章」后需要創建動態,這時golang需要調用python的服務。(這其實很正常,很大的項目也避免不了互相通信的需要。)好在在一臺機器上此問題容易解決的多。

等等,緩存會沖突嗎? 在「數據篇」中講到Frodo是有緩存機制的,現在發現python的前臺和golang的后臺都依賴緩存,這點需要嚴格的key的統一來保證兩個緩存數據的一致性。

Golang的異步與并發

既然將原來python的服務換為golang, 前面提到的異步特性golang能滿足嗎?其實思想是一致的,只是從asycio和可等待對象變為了goroutine, 拿「博文」創建接口舉例:

func CreatePost(data map[string]interface{}) {

post := new(Post)

post.Title = data["title"].(string)

post.Summary = data["summary"].(string)

post.Type = data["type"].(int)

post.CanComment = data["can_comment"].(int)

post.AuthorID = data["author_id"].(int)

post.Status = data["status"].(int)

tags := data["tags"].([]string)

content := data["content"]

DB.Create(&post)

fmt.Println(post)

go post.SetProps("content", content) // go設置內容

go post.UpdateTags(tags) // go 更新標簽

go post.Flush() // go 清除緩存

go CreateActivity(post) // go 創建動態

}

可以看到連續使用了4個go分發不能阻塞的任務,這些都是goroutine, 配套的有對他們管理的通信工具和同步原語,每個goroutine也可以繼續分發協程,如其中的更新標簽:

func (post *Post) UpdateTags(tagNames []string) {

var originTags []Posttag

var originTagNames []string

DB.Where("post_id = ?", post.ID).Find(&originTags)

for _, item := range originTags {

var tag Tag

DB.Select("name").Where("id = ?", item.TagID).First(&tag)

originTagNames = append(originTagNames, tag.Name)

}

_, _, deleteTagNames, addTagNames := goset.Difference(originTagNames, tagNames)

for _, tag := range addTagNames.([]string) {

go CreateTags(tag)

go CreatePostTags(post.ID, tag)

}

for _, tag := range deleteTagNames.([]string) {

go DeletePostTags(post.ID, tag)

}

}

golang沒有類似asyncio.gather(*coros)式的分發,采用for循環是一樣的實現。目前我已經把簡單的系統拆成了兩個不同技術類型的服務,可以見到部署難題漸顯,接下來的更新就是虛擬化解決環境依賴難題和自動化部署了~

總結

以上是生活随笔為你收集整理的python加go_[Python异步博客开发] 加入Golang, go~!的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。