From f43a16383d5ad8dfd16a2a0380d02f2017fbc68b Mon Sep 17 00:00:00 2001 From: caixw Date: Sat, 9 Mar 2024 13:05:58 +0800 Subject: [PATCH] =?UTF-8?q?feat(plugins/compress):=20=E6=B7=BB=E5=8A=A0=20?= =?UTF-8?q?compress?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 +-- go.mod | 8 ++++++ go.sum | 41 ++++++++++++++++++++++++++++ locales/und.yaml | 3 ++ locales/{zh-Hans.yaml => zh-CN.yaml} | 5 +++- middlewares/middlewares.go | 6 ++++ plugins/access/access.go | 2 +- plugins/compress/compress.go | 40 +++++++++++++++++++++++++++ plugins/compress/compress_test.go | 37 +++++++++++++++++++++++++ plugins/plugins.go | 6 ++++ webuse.go | 2 +- 11 files changed, 149 insertions(+), 5 deletions(-) rename locales/{zh-Hans.yaml => zh-CN.yaml} (69%) create mode 100644 middlewares/middlewares.go create mode 100644 plugins/compress/compress.go create mode 100644 plugins/compress/compress_test.go create mode 100644 plugins/plugins.go diff --git a/README.md b/README.md index b3f38ce..f89008b 100644 --- a/README.md +++ b/README.md @@ -10,14 +10,14 @@ ## 插件 -插件位于 plugins 目录之下: +插件位于 [plugins](plugins) 目录之下: - access 客户端访问记录; - health 接口状态的监测; ## 中间件 -中间件位于 middlewares 目录之下: +中间件位于 [middlewares](middlewares) 目录之下: - auth/basic 基本的验证处理; - auth/jwt JSON Web Tokens 中间件; diff --git a/go.mod b/go.mod index b21b385..8e69be4 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ require ( github.com/issue9/assert/v4 v4.1.1 github.com/issue9/cache v0.9.2 github.com/issue9/web v0.87.4 + github.com/shirou/gopsutil/v3 v3.24.2 ) require ( @@ -12,6 +13,7 @@ require ( github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect + github.com/go-ole/go-ole v1.2.6 // indirect github.com/issue9/config v0.6.2 // indirect github.com/issue9/conv v1.3.5 // indirect github.com/issue9/errwrap v0.3.2 // indirect @@ -26,7 +28,13 @@ require ( github.com/issue9/term/v3 v3.2.7 // indirect github.com/issue9/unique/v2 v2.0.1 // indirect github.com/klauspost/compress v1.17.7 // indirect + github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect + github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/redis/go-redis/v9 v9.5.1 // indirect + github.com/shoenig/go-m1cpu v0.1.6 // indirect + github.com/tklauser/go-sysconf v0.3.12 // indirect + github.com/tklauser/numcpus v0.6.1 // indirect + github.com/yusufpapurcu/wmi v1.2.4 // indirect golang.org/x/crypto v0.21.0 // indirect golang.org/x/mod v0.16.0 // indirect golang.org/x/net v0.21.0 // indirect diff --git a/go.sum b/go.sum index 6c34e35..8f580ca 100644 --- a/go.sum +++ b/go.sum @@ -8,10 +8,19 @@ github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/issue9/assert/v4 v4.1.1 h1:OhPE8SB8n/qZCNGLQa+6MQtr/B3oON0JAVj68k8jJlc= github.com/issue9/assert/v4 v4.1.1/go.mod h1:v7qDRXi7AsaZZNh8eAK2rkLJg5/clztqQGA1DRv9Lv4= github.com/issue9/cache v0.9.2 h1:tMvXPhGKBXbSIMHi5qzsdwmQjf7qGYBo1W/LLTDHw9s= @@ -46,21 +55,53 @@ github.com/issue9/web v0.87.4 h1:BD6+ZjSCnlYS6G8j0xOJxmjsHkhaOAPP0Oe5OW3z+3M= github.com/issue9/web v0.87.4/go.mod h1:5nkr+8J/LD1WAyjA/4gmWgi3IOxRV37cR6c3EJ062b8= github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg= github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/redis/go-redis/v9 v9.5.1 h1:H1X4D3yHPaYrkL5X06Wh6xNVM/pX0Ft4RV0vMGvLBh8= github.com/redis/go-redis/v9 v9.5.1/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M= +github.com/shirou/gopsutil/v3 v3.24.2 h1:kcR0erMbLg5/3LcInpw0X/rrPSqq4CDPyI6A6ZRC18Y= +github.com/shirou/gopsutil/v3 v3.24.2/go.mod h1:tSg/594BcA+8UdQU2XcW803GWYgdtauFFPgJCJKZlVk= +github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= +github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= +github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= +github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= +github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= +github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= +github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= +github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= +github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic= golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/locales/und.yaml b/locales/und.yaml index 996d7d4..813eba5 100755 --- a/locales/und.yaml +++ b/locales/und.yaml @@ -3,6 +3,9 @@ messages: - key: can not get the ip message: msg: can not get the ip + - key: enable compression base on cpu used + message: + msg: enable compression base on cpu used - key: not found jwt signing method message: msg: not found jwt signing method diff --git a/locales/zh-Hans.yaml b/locales/zh-CN.yaml similarity index 69% rename from locales/zh-Hans.yaml rename to locales/zh-CN.yaml index 568d684..0cf12f5 100644 --- a/locales/zh-Hans.yaml +++ b/locales/zh-CN.yaml @@ -1,8 +1,11 @@ -id: zh-Hans +id: zh-CN messages: - key: can not get the ip message: msg: 无法获取客户的 IP 地址 + - key: enable compression base on cpu used + message: + msg: 基于 CPU 使用率决定是否启用压缩功能:w - key: not found jwt signing method message: msg: 未找到 JWT 签名方法 diff --git a/middlewares/middlewares.go b/middlewares/middlewares.go new file mode 100644 index 0000000..ba45498 --- /dev/null +++ b/middlewares/middlewares.go @@ -0,0 +1,6 @@ +// SPDX-FileCopyrightText: 2024 caixw +// +// SPDX-License-Identifier: MIT + +// Package middlewares 适用于 [web.Middleware] 的中间件 +package middlewares diff --git a/plugins/access/access.go b/plugins/access/access.go index 2b5663d..e689ec6 100644 --- a/plugins/access/access.go +++ b/plugins/access/access.go @@ -7,7 +7,7 @@ package access import "github.com/issue9/web" -// New 声明 Access 中间件 +// New 声明 [Access] 中间件 // // l 表示记录输出的通道; // format 表示记录的格式,接受三个参数,分别为状态码、请求方法和请求地址, diff --git a/plugins/compress/compress.go b/plugins/compress/compress.go new file mode 100644 index 0000000..6caf226 --- /dev/null +++ b/plugins/compress/compress.go @@ -0,0 +1,40 @@ +// SPDX-FileCopyrightText: 2024 caixw +// +// SPDX-License-Identifier: MIT + +// Package compress 根据 CPU 占用情况决定是否启用压缩 +package compress + +import ( + "time" + + "github.com/issue9/web" + "github.com/shirou/gopsutil/v3/cpu" +) + +// New 根据 CPU 使用率决定是否启用压缩功能 +// +// dur 多少时间检测一次 CPU 的使用率,不能小于 [time.Second]; +// interval 每次检测时读取的时间长度,不能大于 dur; +// percent CPU 的使用率大于此值时将禁用压缩功能; +func New(dur, interval time.Duration, percent float64) web.Plugin { + if dur < interval { + panic("dur 必须大于 interval") + } + + if percent < 0 || percent > 100 { + panic("percent 必须介于 [0,100]") + } + + return web.PluginFunc(func(s web.Server) { + s.Services().AddTicker(web.Phrase("enable compression base on cpu used"), func(now time.Time) error { + if vals, err := cpu.Percent(interval, false); err != nil { + s.Logs().ERROR().Error(err) + } else { + s.SetCompress(vals[0] < percent) + } + + return nil + }, dur, true, false) + }) +} diff --git a/plugins/compress/compress_test.go b/plugins/compress/compress_test.go new file mode 100644 index 0000000..fd40d70 --- /dev/null +++ b/plugins/compress/compress_test.go @@ -0,0 +1,37 @@ +// SPDX-FileCopyrightText: 2024 caixw +// +// SPDX-License-Identifier: MIT + +package compress + +import ( + "testing" + "time" + + "github.com/issue9/assert/v4" + "github.com/issue9/web/server" +) + +func TestNew(t *testing.T) { + a := assert.New(t, false) + + a.PanicString(func() { + New(time.Microsecond, time.Millisecond, 80) + }, "dur 必须大于 interval") + + a.PanicString(func() { + New(time.Millisecond, time.Microsecond, -1) + }, "percent 必须介于 [0,100]") + + a.PanicString(func() { + New(time.Millisecond, time.Microsecond, 101) + }, "percent 必须介于 [0,100]") + + s, err := server.New("test", "1.0.0", nil) + a.NotError(err).NotNil(s) + s.SetCompress(false) + + a.False(s.CanCompress()) + s.Use(New(time.Second, time.Microsecond, 80)) + a.Wait(time.Second).True(s.CanCompress()) +} diff --git a/plugins/plugins.go b/plugins/plugins.go new file mode 100644 index 0000000..4da209b --- /dev/null +++ b/plugins/plugins.go @@ -0,0 +1,6 @@ +// SPDX-FileCopyrightText: 2024 caixw +// +// SPDX-License-Identifier: MIT + +// Package plugins 适用于 [web.Plugin] 的插件 +package plugins diff --git a/webuse.go b/webuse.go index ba71a50..06e6ffa 100644 --- a/webuse.go +++ b/webuse.go @@ -3,7 +3,7 @@ // SPDX-License-Identifier: MIT //go:generate web locale -l=und -m -f=yaml ./ -//go:generate web update-locale -src=./locales/und.yaml -dest=./locales/zh-Hans.yaml +//go:generate web update-locale -src=./locales/und.yaml -dest=./locales/zh-CN.yaml // Package webuse 适用 [web] 的中间件和插件 //