{"id":18942442,"url":"https://github.com/pinguo/pgo","last_synced_at":"2025-04-15T21:31:47.454Z","repository":{"id":57482801,"uuid":"152010746","full_name":"pinguo/pgo","owner":"pinguo","description":"A fast, simple and component based go web framework.","archived":false,"fork":false,"pushed_at":"2019-09-23T03:37:04.000Z","size":242,"stargazers_count":16,"open_issues_count":12,"forks_count":14,"subscribers_count":7,"default_branch":"master","last_synced_at":"2024-06-19T05:57:10.064Z","etag":null,"topics":["component","framework","go","http","web"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pinguo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-10-08T03:01:05.000Z","updated_at":"2024-06-19T05:57:10.064Z","dependencies_parsed_at":"2022-09-03T09:51:29.770Z","dependency_job_id":null,"html_url":"https://github.com/pinguo/pgo","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pinguo%2Fpgo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pinguo%2Fpgo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pinguo%2Fpgo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pinguo%2Fpgo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pinguo","download_url":"https://codeload.github.com/pinguo/pgo/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223685654,"owners_count":17185890,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["component","framework","go","http","web"],"created_at":"2024-11-08T12:32:54.310Z","updated_at":"2024-11-08T12:32:54.645Z","avatar_url":"https://github.com/pinguo.png","language":"Go","readme":"# PGO\nPGO应用框架即\"Pinguo GO application framework\"，是Camera360广告服务端团队研发的一款简单、高性能、组件化的GO应用框架。受益于GO语言高性能与原生协程，业务从php+yii2升级到PGO后，线上表现单机处理能力提高10倍。PGO吸收了php-yii2/php-msf/go-gin等框架的设计思想，平衡了开发效率和运行性能，使用PGO可快速地开发出高性能的web应用程序。\n\n参考文档：[pgo-docs](https://github.com/pinguo/pgo-docs)\n\n应用示例：[pgo-demo](https://github.com/pinguo/pgo-demo)\n\n## 基准测试\n主要测试PGO框架与php-yii2，php-msf，go-gin的性能差异。\n\n说明:\n- 测试机为4核8G虚拟机\n- php版本为7.1.24, 开启opcache\n- go版本为1.11.2, GOMAXPROCS=4\n- swoole版本1.9.21, worker_num=4, reactor_num=2\n- 输出均为字符串{\"code\": 200, \"message\": \"success\",\"data\": \"hello world\"}\n- 命令: ab -n 1000000 -c 100 -k 'http://target-ip:8000/welcome'\n\n分类 | QPS | 平均响应时间(ms) |CPU\n---- | ---- | ---- | -----\nphp-yii2 | 2715 | 36.601 | 72%\nphp-msf | 20053 | 4.575 | 73%\ngo-gin | 41798 | 2.339 | 55%\ngo-pgo | 33902 | 2.842 | 64%\n\n结论:\n- pgo相比yii2性能提升10+倍, 对低于php7的版本性能还要翻倍。\n- pgo相比msf性能提升70%, 相较于msf的yield模拟的协程，pgo协程理解和使用更简单。\n- pgo相比gin性能降低19%, 但pgo内置多种常用组件，工程化做得更好，使用方式类似yii2和msf。\n\n## 环境要求\n- GO 1.10+\n- Make 3.8+\n- Linux/MacOS/Cygwin\n- Glide 0.13+ (建议)\n- GoLand 2018 (建议)\n\n## 项目目录\n规范：\n- 一个项目为一个独立的目录，不使用GO全局工作空间。\n- 项目的GOPATH为项目根目录，不要依赖系统的GOPATH。\n- 除GO标准库外，所有外部依赖代码放入\"src/vendor\"。\n- 项目源码文件与目录使用大写驼峰(CamelCase)形式。\n\n```\n\u003cproject\u003e\n├── bin/                # 编译程序目录\n├── conf/               # 配置文件目录\n│   ├── production/     # 环境配置目录\n│   │   ├── app.yaml\n│   │   └── params.yaml\n│   ├── testing/\n│   ├── app.yaml        # 项目配置文件\n│   └── params.yaml     # 自定义配置文件\n├── makefile            # 编译打包\n├── runtime/            # 运行时目录\n├── public/             # 静态资源目录\n├── view/               # 视图模板目录\n└── src/                # 项目源码目录\n    ├── Command/        # 命令行控制器目录\n    ├── Controller/     # HTTP控制器目录\n    ├── Lib/            # 项目基础库目录\n    ├── Main/           # 项目入口目录\n    ├── Model/          # 模型目录(数据交互)\n    ├── Service/        # 服务目录(业务逻辑)\n    ├── Struct/         # 结构目录(数据定义)\n    ├── Test/           # 测试目录\n    ├── vendor/         # 第三方依赖目录\n    ├── glide.lock      # 项目依赖锁文件\n    └── glide.yaml      # 项目依赖配置文件\n```\n\n## 依赖管理\n建议使用glide做为依赖管理工具(类似php的composer)，不使用go官方的dep工具\n\n安装(mac)：`brew install glide`\n\n使用(调用目录为项目的src目录)：\n```\nglide init              # 初始化项目\nglide get \u003cpkg\u003e         # 下载pkg并添加依赖\n    --all-dependencies  # 下载pkg的所有依赖\nglide get \u003cpkg\u003e#v1.2    # 下载指定版本的pkg\nglide install           # 根据lock文件下载依赖\nglide update            # 更新依赖包\n```\n\n## 快速开始\n1. 拷贝makefile\n    \n    非IDE环境(命令行)下，推荐使用make做为编译打包的控制工具，从[pgo](https://github.com/pinguo/pgo)或[pgo-demo](https://github.com/pinguo/pgo-demo)将makefile复制到项目目录下。\n    ```sh\n    make start      # 编译并运行当前工程\n    make stop       # 停止当前工程的进程\n    make build      # 仅编译当前工程\n    make update     # 更新glide依赖(递归更新)\n    make install    # 安装glide.lock文件锁定的依赖包\n    make pgo        # 安装pgo框架到当前工程\n    make init       # 初始化工程目录\n    make help       # 输出帮助信息\n    ```\n\n2. 创建项目目录(以下三种方法均可)\n    - 执行`make init`创建目录\n    - 参见《项目目录》手动创建\n    - 从[pgo-demo](https://github.com/pinguo/pgo-demo)克隆目录结构\n\n3. 修改配置文件(conf/app.yaml)\n    ```yaml\n    name: \"pgo-demo\"\n    GOMAXPROCS: 2\n    runtimePath: \"@app/runtime\"\n    publicPath: \"@app/public\"\n    viewPath: \"@app/view\"\n    server:\n        httpAddr: \"0.0.0.0:8000\"\n        readTimeout: \"30s\"\n        writeTimeout: \"30s\"\n    components:\n        log:\n            levels: \"ALL\"\n            targets:\n                info:\n                    class: \"@pgo/FileTarget\"\n                    levels: \"DEBUG,INFO,NOTICE\"\n                    filePath: \"@runtime/info.log\"\n                error:\n                    class: \"@pgo/FileTarget\"\n                    levels: \"WARN,ERROR,FATAL\"\n                    filePath: \"@runtime/error.log\"\n                console: \n                    class: \"@pgo/ConsoleTarget\"\n                    levels: \"ALL\"\n    ```\n\n4. 安装PGO(以下两种方法均可)\n    - 在项目根目录执行`make pgo`安装PGO\n    - 在项目根目录执行`export GOPATH=$GOPATH:$(pwd) \u0026\u0026 cd src \u0026\u0026 glide get github.com/pinguo/pgo \u0026\u0026 glide update`\n5. 创建Service(src/Service/Welcome.go)\n    ```go\n    package Service\n\n    import (\n        \"fmt\"\n\n        \"github.com/pinguo/pgo\"\n    )\n\n    type Welcome struct {\n        pgo.Object\n    }\n\n    // 框架自动调用的构造函数(可选)\n    func (w *Welcome) Construct() {\n        fmt.Printf(\"call in Service/Welcome.Construct\\n\")\n    }\n\n    // 框架自动调用的初始函数(可选)\n    func (w *Welcome) Init() {\n        fmt.Printf(\"call in Service/Welcome.Init\\n\")\n    }\n\n    func (w *Welcome) SayHello(name string, age int, sex string) {\n        fmt.Printf(\"call in  Service/Welcome.SayHello, name:%s age:%d sex:%s\\n\", name, age, sex)\n    }\n    ```\n6. 注册Service(src/Service/Init.go)\n    \n    ```go\n    package Service\n\n    import \"github.com/pinguo/pgo\"\n\n    func init() {\n        container := pgo.App.GetContainer()\n\n        // 注册类\n        container.Bind(\u0026Welcome{})\n\n        // 除控制器目录外，其它包的init函数中应该只注册该包的类，\n        // 而不应该包含子包。\n    }\n\n    ```\n7. 创建控制器(src/Controller/WelcomeController.go)\n    ```go\n    package Controller\n\n    import (\n        \"Service\"\n        \"net/http\"\n     \n        \"github.com/pinguo/pgo\"\n    )\n\n    type WelcomeController struct {\n        pgo.Controller\n    }\n\n    // 默认动作为index, 通过/welcome或/welcome/index调用\n    func (w *WelcomeController) ActionIndex() {\n        w.OutputJson(\"hello world\", http.StatusOK)\n    }\n    \n    // URL路由动作，根据url自动映射控制器及方法，不需要配置.\n    // url的最后一段为动作名称，不存在则为index,\n    // url的其余部分为控制器名称，不存在则为index,\n    // 例如：/welcome/say-hello，控制器类名为\n    // Controller/WelcomeController 动作方法名为ActionSayHello\n    func (w *WelcomeController) ActionSayHello() {\n        ctx := w.GetContext() // 获取PGO请求上下文件\n    \n        // 验证参数，提供参数名和默认值，当不提供默认值时，表明该参数为必选参数。\n        // 详细验证方法参见Validate.go\n        name := ctx.ValidateParam(\"name\").Min(5).Max(50).Do() // 验证GET/POST参数(string)，为空或验证失败时panic\n        age := ctx.ValidateQuery(\"age\", 20).Int().Min(1).Max(100).Do() // 只验证GET参数(int)，为空或失败时返回20\n        ip := ctx.ValidatePost(\"ip\", \"\").IPv4().Do() // 只验证POST参数(string), 为空或失败时返回空字符串\n    \n        // 打印日志\n        ctx.Info(\"request from welcome, name:%s, age:%d, ip:%s\", name, age, ip)\n        ctx.PushLog(\"clientIp\", ctx.GetClientIp()) // 生成clientIp=xxxxx在pushlog中\n    \n        // 调用业务逻辑，一个请求生命周期内的对象都要通过GetObject()获取，\n        // 这样可自动查找注册的类，并注入请求上下文(Context)到对象中。\n        svc := w.GetObject(\"Service/Welcome\").(*Service.Welcome)\n    \n        // 添加耗时到profile日志中\n        ctx.ProfileStart(\"Welcome.SayHello\")\n        svc.SayHello(name, age, ip)\n        ctx.ProfileStop(\"Welcome.SayHello\")\n    \n        data := pgo.Map{\n            \"name\": name,\n            \"age\": age,\n            \"ip\": ip,\n        }\n    \n        // 输出json数据\n        w.OutputJson(data, http.StatusOK)\n    }\n    \n    // 正则路由动作，需要配置Router组件(components.router.rules)\n    // 规则中捕获的参数通过动作函数参数传递，没有则为空字符串.\n    // eg. \"^/reg/eg/(\\\\w+)/(\\\\w+)$ =\u003e /welcome/regexp-example\"\n    func (w *WelcomeController) ActionRegexpExample(p1, p2 string) {\n        data := pgo.Map{\"p1\": p1, \"p2\": p2}\n        w.OutputJson(data, http.StatusOK)\n    }\n    \n    // RESTFULL动作，url中没有指定动作名，使用请求方法作为动作的名称(需要大写)\n    // 例如：GET方法请求ActionGET(), POST方法请求ActionPOST()\n    func (w *WelcomeController) ActionGET() {\n        w.GetContext().End(http.StatusOK, []byte(\"call restfull GET\"))\n    }\n    ```\n8. 注册控制器(src/Controller/Init.go)\n    ```go\n    package Controller\n\n    import \"github.com/pinguo/pgo\"\n\n    func init() {\n        container := pgo.App.GetContainer()\n        container.Bind(\u0026WelcomeController{})\n    }\n    ```\n9. 创建程序入口(src/Main/main.go)\n    ```go\n    package main\n\n    import (\n        _ \"Controller\" // 导入控制器\n\n        \"github.com/pinguo/pgo\"\n    )\n\n    func main() {\n        pgo.Run() // 运行程序\n    }\n    ```\n10. 编译运行\n    ```sh\n    make update\n    make start\n    curl http://127.0.0.1:8000/welcome\n    ```\n\n### 其它\n参见[pgo-docs](https://github.com/pinguo/pgo-docs)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpinguo%2Fpgo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpinguo%2Fpgo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpinguo%2Fpgo/lists"}