├── .gitignore ├── README.md ├── archaius ├── cse │ ├── README.md │ ├── conf │ │ ├── auth.yaml │ │ ├── chassis.yaml │ │ └── microservice.yaml │ ├── img │ │ ├── cse-1-json.png │ │ ├── cse-1-kv.png │ │ ├── cse-2-json.png │ │ ├── cse-2-kv.png │ │ ├── cse-3-json.png │ │ └── cse-3-kv.png │ ├── main.go │ └── props.json ├── local │ ├── README.md │ ├── conf │ │ ├── chassis.yaml │ │ ├── custom.yaml │ │ ├── microservice.yaml │ │ └── props.yaml │ └── main.go └── resource │ └── restful_hello.go ├── canaryrelease ├── README.md ├── client │ ├── conf │ │ ├── chassis.yaml │ │ ├── microservice.yaml │ │ └── router.yaml │ └── main.go ├── serverV1 │ ├── conf │ │ ├── chassis.yaml │ │ └── microservice.yaml │ ├── main.go │ └── resource │ │ └── restful_router_V1.go └── serverV2 │ ├── conf │ ├── chassis.yaml │ └── microservice.yaml │ ├── main.go │ └── resource │ └── restful_router_V2.go ├── circuit ├── README.md ├── client │ ├── conf │ │ ├── chassis.yaml │ │ ├── circuit_breaker.yaml │ │ ├── microservice.yaml │ │ └── monitoring.yaml │ └── main.go └── server │ ├── conf │ ├── chassis.yaml │ ├── circuit_breaker.yaml │ └── microservice.yaml │ ├── main.go │ └── resource │ └── restful_hello.go ├── docker-compose.yaml ├── eurekapp ├── README.md ├── conf │ ├── chassis.yaml │ ├── lager.yaml │ └── microservice.yaml ├── controller │ └── price.go ├── go.mod ├── main.go └── router │ └── router.go ├── go.mod ├── grace ├── README.md ├── client │ ├── conf │ │ ├── chassis.yaml │ │ └── microservice.yaml │ └── main.go └── server │ ├── conf │ ├── chassis.yaml │ └── microservice.yaml │ ├── main.go │ └── resource │ └── restful_hello.go ├── grpc ├── README.md ├── bench │ ├── conf │ │ ├── chassis.yaml │ │ └── microservice.yaml │ └── main.go ├── client │ ├── conf │ │ ├── chassis.yaml │ │ └── microservice.yaml │ └── main.go ├── helloworld │ ├── helloworld.pb.go │ └── helloworld.proto └── server │ ├── conf │ ├── chassis.yaml │ └── microservice.yaml │ └── main.go ├── hello ├── client │ ├── conf │ │ ├── chassis.yaml │ │ └── microservice.yaml │ └── main.go ├── go.mod └── server │ ├── conf │ ├── chassis.yaml │ └── microservice.yaml │ └── main.go ├── java-call-go ├── README.md ├── order │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── com │ │ │ └── xxx │ │ │ └── order │ │ │ ├── Application.java │ │ │ ├── Data.java │ │ │ ├── ErrorCode.java │ │ │ ├── OrderController.java │ │ │ └── OrderService.java │ │ └── resources │ │ ├── META-INF │ │ └── MANIFEST.MF │ │ └── microservice.yaml └── price │ ├── conf │ ├── PriceServer │ │ └── schema │ │ │ └── PriceServer.yaml │ ├── chassis.yaml │ └── microservice.yaml │ ├── controller │ └── price.go │ └── main.go ├── metrics ├── README.md └── server │ ├── conf │ ├── auth.yaml │ ├── chassis.yaml │ └── microservice.yaml │ ├── main.go │ └── schema │ └── schema.go ├── monitoring ├── README.md ├── client │ ├── conf │ │ ├── chassis.yaml │ │ ├── microservice.yaml │ │ └── monitoring.yaml │ └── main.go ├── serverA │ ├── conf │ │ ├── chassis.yaml │ │ ├── microservice.yaml │ │ └── monitoring.yaml │ └── main.go └── serverB │ ├── conf │ ├── chassis.yaml │ ├── microservice.yaml │ └── monitoring.yaml │ └── main.go ├── mutualtls ├── README.md ├── client │ ├── client.crt │ ├── client.key │ ├── conf │ │ ├── chassis.yaml │ │ ├── microservice.yaml │ │ └── tls.yaml │ ├── main.go │ └── server.crt └── server │ ├── client.crt │ ├── conf │ ├── TLSService │ │ └── schema │ │ │ └── TLSService.yaml │ ├── chassis.yaml │ ├── microservice.yaml │ └── tls.yaml │ ├── main.go │ ├── pwd │ ├── server.crt │ └── server.key ├── protocol ├── README.md ├── gofiber │ └── server │ │ ├── conf │ │ ├── chassis.yaml │ │ └── microservice.yaml │ │ └── main.go └── gorestful │ ├── conf │ ├── chassis.yaml │ └── microservice.yaml │ └── main.go ├── router └── servicecomb │ ├── README.md │ ├── client │ ├── conf │ │ ├── chassis.yaml │ │ ├── microservice.yaml │ │ └── router.yaml │ └── main.go │ ├── resource │ ├── restful_router_V1.go │ └── restful_router_V2.go │ ├── serverV1 │ ├── conf │ │ ├── chassis.yaml │ │ ├── microservice.yaml │ │ └── paymentService │ │ │ └── schema │ │ │ └── paymentService.yaml │ └── main.go │ └── serverV2 │ ├── conf │ ├── chassis.yaml │ └── microservice.yaml │ └── main.go ├── router_url └── server │ ├── README.md │ ├── conf │ ├── chassis.yaml │ └── microservice.yaml │ ├── main.go │ └── schema │ └── schema.go └── tls ├── README.md ├── client ├── conf │ ├── chassis.yaml │ ├── microservice.yaml │ └── tls.yaml └── main.go └── server ├── conf ├── chassis.yaml ├── microservice.yaml └── tls.yaml ├── main.go ├── pwd ├── server.crt └── server.key /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Example user template template 3 | ### Example user template 4 | 5 | # IntelliJ project files 6 | .idea 7 | *.iml 8 | log 9 | *.log 10 | main 11 | go.sum 12 | out 13 | gen### Go template 14 | # Binaries for programs and plugins 15 | *.exe 16 | *.exe~ 17 | *.dll 18 | *.so 19 | *.dylib 20 | **/main 21 | **/*log 22 | # Test binary, build with `go test -c` 23 | *.test 24 | 25 | # Output of the go coverage tool, specifically when used with LiteIDE 26 | *.out 27 | 28 | vendor -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # go-chassis-examples 2 | 3 | this repo holds go-chassis examples 4 | 5 | 6 | 1.most of examples can run with Apache ServiceComb service center 7 | launch service center with docker compose 8 | ```sh 9 | cd go-chassis-examples 10 | sudo docker-compose up 11 | ``` 12 | 13 | 2.example of kubernetes and istio requires you run example in complicated environment 14 | that you must deploy yourself 15 | 16 | 3.example of huawei cloud, 17 | you need to register huawei cloud account to use https://www.huaweicloud.com/product/servicestage.html 18 | 19 | # Dependencies 20 | all of examples share same dependency management in go.mod. 21 | 22 | before you start you must download all dependencies with go mod. 23 | 24 | how to use go mod(go 1.11+, experimental but a recommended way) 25 | ```shell 26 | cd go-chassis-examples 27 | GO111MODULE=on go mod download 28 | #optional 29 | GO111MODULE=on go mod vendor 30 | ``` 31 | 32 | 33 | # Scenarios 34 | 35 | ## distributed configuration management 36 | 37 | ## canary release 38 | 39 | ## protect you system with circuit breaker to prevent cascade failure 40 | 41 | ## mutual TLS -------------------------------------------------------------------------------- /archaius/cse/README.md: -------------------------------------------------------------------------------- 1 | This demo show how to mange your custom configurations for archaius 2 | 3 | archaius support json file and key: value to mange you custom . Notice here you customized 4 | keys are not GO-Chassis governance 5 | 6 | ## json file 7 | JSON file: batch mange you custom configurations 8 | 9 | ```json 10 | { 11 | "a.user":"peter", 12 | "its.pwd":"123" 13 | } 14 | ``` 15 | 16 | ## key:value 17 | use key:value one-by-one mange you custom configurations 18 | ```text 19 | "a.user":"peter" 20 | ``` 21 | ## Archaius 22 | 23 | how to use archaius for huawei cloud 24 | 25 | ### json 26 | 27 | * Click the button `Import` 28 | ![]( img/cse-1-json.png) 29 | 30 | * choose json file and then click the button `Upload` to upload file 31 | ![]( img/cse-2-json.png) 32 | 33 | * uploaded json file successfully , you can see config 34 | ![]( img/cse-3-json.png) 35 | * call the api `/props/its.pwd` will reply `123` 36 | 37 | ### key:value 38 | 39 | * Click the button `Create Configuration` 40 | ![]( img/cse-1-kv.png) 41 | 42 | * input `key` any `value` 43 | ![]( img/cse-2-kv.png) 44 | 45 | * set config successfully , you can see this 46 | ![]( img/cse-3-kv.png) 47 | 48 | * call api `/props/c.name` success will reply `test-name` -------------------------------------------------------------------------------- /archaius/cse/conf/auth.yaml: -------------------------------------------------------------------------------- 1 | cse: 2 | credentials: 3 | accessKey: 4 | secretKey: 5 | project: 6 | akskCustomCipher: default -------------------------------------------------------------------------------- /archaius/cse/conf/chassis.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | cse: 3 | service: 4 | registry: 5 | type: servicecenter 6 | scope: full 7 | refreshInterval : 10s 8 | address: https://cse.cn-north-1.myhuaweicloud.com 9 | refeshInterval : 1 10 | watch: true 11 | config: 12 | client: 13 | serverUri: https://cse.cn-north-1.myhuaweicloud.com 14 | protocols: 15 | rest: 16 | listenAddress: 127.0.0.1:8080 17 | advertiseAddress: 127.0.0.1:8080 18 | handler: 19 | chain: 20 | Consumer: 21 | default: bizkeeper-consumer, router, loadbalance,ratelimiter-consumer,transport -------------------------------------------------------------------------------- /archaius/cse/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | #微服务的私有属性 3 | service_description: 4 | name: RESTClient -------------------------------------------------------------------------------- /archaius/cse/img/cse-1-json.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/go-chassis/go-chassis-examples/a17039513884f935ef7bbde7827faf87d709ec97/archaius/cse/img/cse-1-json.png -------------------------------------------------------------------------------- /archaius/cse/img/cse-1-kv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/go-chassis/go-chassis-examples/a17039513884f935ef7bbde7827faf87d709ec97/archaius/cse/img/cse-1-kv.png -------------------------------------------------------------------------------- /archaius/cse/img/cse-2-json.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/go-chassis/go-chassis-examples/a17039513884f935ef7bbde7827faf87d709ec97/archaius/cse/img/cse-2-json.png -------------------------------------------------------------------------------- /archaius/cse/img/cse-2-kv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/go-chassis/go-chassis-examples/a17039513884f935ef7bbde7827faf87d709ec97/archaius/cse/img/cse-2-kv.png -------------------------------------------------------------------------------- /archaius/cse/img/cse-3-json.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/go-chassis/go-chassis-examples/a17039513884f935ef7bbde7827faf87d709ec97/archaius/cse/img/cse-3-json.png -------------------------------------------------------------------------------- /archaius/cse/img/cse-3-kv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/go-chassis/go-chassis-examples/a17039513884f935ef7bbde7827faf87d709ec97/archaius/cse/img/cse-3-kv.png -------------------------------------------------------------------------------- /archaius/cse/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/go-chassis/go-chassis-examples/archaius/resource" 5 | "github.com/go-chassis/go-chassis/v2" 6 | "github.com/go-chassis/go-chassis/v2/core/server" 7 | "github.com/go-chassis/openlog" 8 | ) 9 | 10 | func main() { 11 | chassis.RegisterSchema("rest", &resource.Hello{}, server.WithSchemaID("Hello")) 12 | err := chassis.Init() 13 | if err != nil { 14 | openlog.Error(err.Error()) 15 | return 16 | } 17 | chassis.Run() 18 | } 19 | -------------------------------------------------------------------------------- /archaius/cse/props.json: -------------------------------------------------------------------------------- 1 | { 2 | "a.user":"peter", 3 | "its.pwd":"123" 4 | } -------------------------------------------------------------------------------- /archaius/local/README.md: -------------------------------------------------------------------------------- 1 | This demo show how to mange your custom configurations in local file system 2 | 3 | it include 2 custom files. 4 | 5 | # custom.yaml 6 | this file's name is considered as key and content of file is considered as value 7 | ```go 8 | archaius.AddFile("./conf/custom.yaml", 9 | archaius.WithFileHandler(filesource.UseFileNameAsKeyContentAsValue)) 10 | ``` 11 | 12 | # props.yaml 13 | each of key value in file is considered as key value 14 | ```go 15 | archaius.AddFile("./conf/props.yaml") 16 | ``` 17 | 18 | See results 19 | ```sh 20 | go build main.go 21 | ./main 22 | ``` 23 | 24 | call http://127.0.0.1:5001/file to see custom.yaml 25 | 26 | call http://127.0.0.1:5001/props/{key} to see props.yaml value 27 | 28 | you can change file content of any file in runtime, 29 | and call API to see that config has been changed in runtime. 30 | 31 | NOTICE: In distributed system you can change key value in a config server 32 | to manipulate configurations in runtime, 33 | just like you change value by changing file content. 34 | go-archaius use config client to interact with config server. 35 | Check https://github.com/go-chassis/go-cc-client to see config center client implementation 36 | -------------------------------------------------------------------------------- /archaius/local/conf/chassis.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | cse: 3 | service: 4 | registry: 5 | address: http://127.0.0.1:30100 # If type is File then address will be the path of the file 6 | protocols: 7 | rest: 8 | listenAddress: "127.0.0.1:5001" 9 | #advertiseAddress: "internal_ip:5001" 10 | handler: 11 | chain: 12 | Provider: 13 | default: tracing-provider,bizkeeper-provider -------------------------------------------------------------------------------- /archaius/local/conf/custom.yaml: -------------------------------------------------------------------------------- 1 | user: peter 2 | pwd: 123 -------------------------------------------------------------------------------- /archaius/local/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | #微服务的私有属性 3 | service_description: 4 | name: RESTServer -------------------------------------------------------------------------------- /archaius/local/conf/props.yaml: -------------------------------------------------------------------------------- 1 | a.user: peter 2 | its.pwd: 123 -------------------------------------------------------------------------------- /archaius/local/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/go-chassis/go-archaius" 5 | "github.com/go-chassis/go-archaius/source/util" 6 | "github.com/go-chassis/go-chassis-examples/archaius/resource" 7 | "github.com/go-chassis/go-chassis/v2" 8 | "github.com/go-chassis/openlog" 9 | ) 10 | 11 | //if you use go run main.go instead of binary run, plz export CHASSIS_HOME=/{path}/{to}/server/ 12 | 13 | func main() { 14 | chassis.RegisterSchema("rest", &resource.Hello{}) 15 | if err := chassis.Init(); err != nil { 16 | openlog.Error("Init failed." + err.Error()) 17 | return 18 | } 19 | //Add your custom file to archaius 20 | if err := archaius.AddFile("./conf/custom.yaml", archaius.WithFileHandler(util.UseFileNameAsKeyContentAsValue)); err != nil { 21 | openlog.Error("add file configurations failed." + err.Error()) 22 | return 23 | } 24 | //Add your custom file to archaius 25 | if err := archaius.AddFile("./conf/props.yaml"); err != nil { 26 | openlog.Error("add props configurations failed." + err.Error()) 27 | return 28 | } 29 | chassis.Run() 30 | } 31 | -------------------------------------------------------------------------------- /archaius/resource/restful_hello.go: -------------------------------------------------------------------------------- 1 | package resource 2 | 3 | import ( 4 | "net/http" 5 | 6 | "github.com/go-chassis/go-archaius" 7 | rf "github.com/go-chassis/go-chassis/v2/server/restful" 8 | "sync" 9 | ) 10 | 11 | type Hello struct { 12 | lock sync.Mutex 13 | } 14 | 15 | func (r *Hello) GetFileContent(b *rf.Context) { 16 | b.WriteHeader(http.StatusOK) 17 | //get content of a file 18 | b.Write([]byte(archaius.GetString("custom.yaml", "default"))) 19 | return 20 | } 21 | func (r *Hello) GetProps(b *rf.Context) { 22 | b.WriteHeader(http.StatusOK) 23 | k := b.ReadPathParameter("key") 24 | //get single key value 25 | b.Write([]byte(archaius.GetString(k, "default"))) 26 | return 27 | } 28 | 29 | //URLPatterns helps to respond for corresponding API calls 30 | func (r *Hello) URLPatterns() []rf.Route { 31 | return []rf.Route{ 32 | {Method: http.MethodGet, Path: "/file", ResourceFuncName: "GetFileContent"}, 33 | {Method: http.MethodGet, Path: "/props/{key}", ResourceFuncName: "GetProps"}, 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /canaryrelease/README.md: -------------------------------------------------------------------------------- 1 | this demo shows how to leverage router management to make a canary release 2 | 3 | we have 2 version of cart service 4 | in folders serviceV1 and service V2 5 | 6 | the response is different 7 | ```go 8 | // Equal is method to compare given num and slice sum 9 | func (r *RestFulRouterA) Get(context *restful.Context) { 10 | context.Write([]byte("version 1.0")) 11 | } 12 | 13 | ``` 14 | ```go 15 | // Equal is method to compare given num and slice sum 16 | func (r *RestFulRouterA) Get(context *restful.Context) { 17 | context.Write([]byte("version 1.1")) 18 | } 19 | 20 | ``` 21 | 22 | here is a configuration is consumer side 23 | 24 | ```yaml 25 | routeRule: 26 | carts: 27 | - precedence: 2 28 | match: 29 | headers: 30 | Os: 31 | regex: ios 32 | route: 33 | - weight: 100 34 | tags: 35 | version: 1.1 36 | - precedence: 1 37 | route: 38 | - weight: 100 39 | tags: 40 | version: 1.0 41 | ``` 42 | 43 | it means if header key "Os"'s value is ios 44 | then all the request should be route to version 1.1. 45 | Other request router to 1.0 46 | 47 | you can build and run to see results 48 | 49 | ```shell 50 | cd serverV1 51 | go build main.go 52 | ./main 53 | ``` 54 | ```shell 55 | cd serverV2 56 | go build main.go 57 | ./main 58 | ``` 59 | 60 | ```shell 61 | cd client 62 | go build main.go 63 | ./main 64 | ``` -------------------------------------------------------------------------------- /canaryrelease/client/conf/chassis.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | #APPLICATION_ID: CSE optional 3 | cse: 4 | service: 5 | registry: 6 | address: http://127.0.0.1:30100 7 | -------------------------------------------------------------------------------- /canaryrelease/client/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | #微服务的私有属性 3 | service_description: 4 | name: mall -------------------------------------------------------------------------------- /canaryrelease/client/conf/router.yaml: -------------------------------------------------------------------------------- 1 | routeRule: 2 | carts: | 3 | - precedence: 2 4 | match: 5 | headers: 6 | Os: 7 | regex: ios 8 | route: 9 | - weight: 100 10 | tags: 11 | version: 1.1 12 | - precedence: 1 13 | route: 14 | - weight: 100 15 | tags: 16 | version: 1.0 17 | -------------------------------------------------------------------------------- /canaryrelease/client/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "time" 6 | 7 | _ "github.com/go-chassis/go-chassis/bootstrap" 8 | "github.com/go-chassis/go-chassis/client/rest" 9 | "github.com/go-chassis/go-chassis/core" 10 | "github.com/go-chassis/go-chassis/pkg/util/httputil" 11 | "github.com/go-chassis/go-chassis/v2" 12 | "github.com/go-chassis/openlog" 13 | ) 14 | 15 | //if you use go run main.go instead of binary run, plz export CHASSIS_HOME=/{path}/{to}/rest/client/ 16 | 17 | // Implement grayscale publishing of the application,version A is you old service ,version B is you 18 | // new service.you want to small request to access you new service to test new service of new function 19 | 20 | func main() { 21 | //Init framework 22 | if err := chassis.Init(); err != nil { 23 | openlog.Error("Init failed." + err.Error()) 24 | return 25 | } 26 | 27 | for i := 0; i < 10; i++ { 28 | req, err := rest.NewRequest("GET", "http://carts/list", nil) 29 | if err != nil { 30 | openlog.Error("new request failed.") 31 | return 32 | } 33 | 34 | //req.Header.Set("Chassis", "info") 35 | 36 | resp, err := core.NewRestInvoker().ContextDo(context.Background(), req) 37 | if err != nil { 38 | openlog.Error("do request failed.") 39 | return 40 | } 41 | defer resp.Body.Close() 42 | openlog.Info("carts Server return : " + string(httputil.ReadBody(resp))) 43 | 44 | time.Sleep(1 * time.Second) 45 | } 46 | 47 | for i := 0; i < 10; i++ { 48 | req, err := rest.NewRequest("GET", "http://carts/list", nil) 49 | if err != nil { 50 | openlog.Error("new request failed.") 51 | return 52 | } 53 | 54 | req.Header.Set("os", "ios") 55 | 56 | resp, err := core.NewRestInvoker().ContextDo(context.Background(), req) 57 | if err != nil { 58 | openlog.Error("do request failed.") 59 | return 60 | } 61 | defer resp.Body.Close() 62 | openlog.Info("carts Server return : " + string(httputil.ReadBody(resp))) 63 | 64 | time.Sleep(1 * time.Second) 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /canaryrelease/serverV1/conf/chassis.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | cse: 3 | service: 4 | registry: 5 | address: http://127.0.0.1:30100 # If type is File then address will be the path of the file 6 | protocols: 7 | rest: 8 | listenAddress: 127.0.0.1:5002 9 | advertiseAddress: 127.0.0.1:5002 10 | handler: 11 | chain: 12 | Provider: 13 | default: tracing-provider,bizkeeper-provider -------------------------------------------------------------------------------- /canaryrelease/serverV1/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | #Private property of microservices 3 | service_description: 4 | name: carts 5 | version: 1.0 -------------------------------------------------------------------------------- /canaryrelease/serverV1/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/go-chassis/go-chassis-examples/canaryrelease/serverV1/resource" 5 | "github.com/go-chassis/go-chassis/v2" 6 | "github.com/go-chassis/openlog" 7 | ) 8 | 9 | //if you use go run main.go instead of binary run, plz export CHASSIS_HOME=/{path}/{to}/rpc/server/ 10 | 11 | func main() { 12 | chassis.RegisterSchema("rest", &resource.RestFulRouterA{}) 13 | if err := chassis.Init(); err != nil { 14 | openlog.Error("Init failed." + err.Error()) 15 | return 16 | } 17 | chassis.Run() 18 | } 19 | -------------------------------------------------------------------------------- /canaryrelease/serverV1/resource/restful_router_V1.go: -------------------------------------------------------------------------------- 1 | package resource 2 | 3 | import ( 4 | "github.com/go-chassis/go-chassis/v2/server/restful" 5 | "net/http" 6 | ) 7 | 8 | // RestFulRouterA is a struct used for implementation of restfull router program 9 | type RestFulRouterA struct { 10 | } 11 | 12 | // Equal is method to compare given num and slice sum 13 | func (r *RestFulRouterA) Get(context *restful.Context) { 14 | context.Write([]byte("version 1.0")) 15 | } 16 | 17 | // URLPatterns helps to respond for corresponding API calls 18 | func (r *RestFulRouterA) URLPatterns() []restful.Route { 19 | return []restful.Route{ 20 | {Method: http.MethodGet, Path: "/list", ResourceFuncName: "Get"}, 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /canaryrelease/serverV2/conf/chassis.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | cse: 3 | service: 4 | registry: 5 | address: http://127.0.0.1:30100 # If type is File then address will be the path of the file 6 | protocols: 7 | rest: 8 | listenAddress: 127.0.0.1:5001 9 | advertiseAddress: 127.0.0.1:5001 10 | handler: 11 | chain: 12 | Provider: 13 | default: tracing-provider,bizkeeper-provider -------------------------------------------------------------------------------- /canaryrelease/serverV2/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | #微服务的私有属性 3 | service_description: 4 | name: carts 5 | version: 1.1 -------------------------------------------------------------------------------- /canaryrelease/serverV2/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/go-chassis/go-chassis-examples/canaryrelease/serverV2/resource" 5 | "github.com/go-chassis/go-chassis/v2" 6 | "github.com/go-chassis/openlog" 7 | ) 8 | 9 | //if you use go run main.go instead of binary run, plz export CHASSIS_HOME=/{path}/{to}/rpc/server/ 10 | 11 | func main() { 12 | chassis.RegisterSchema("rest", &resource.RestFulRouterB{}) 13 | if err := chassis.Init(); err != nil { 14 | openlog.Error("Init failed." + err.Error()) 15 | return 16 | } 17 | chassis.Run() 18 | } 19 | -------------------------------------------------------------------------------- /canaryrelease/serverV2/resource/restful_router_V2.go: -------------------------------------------------------------------------------- 1 | package resource 2 | 3 | import ( 4 | "github.com/go-chassis/go-chassis/v2/server/restful" 5 | "net/http" 6 | ) 7 | 8 | // RestFulRouterA is a struct used for implementation of restfull router program 9 | type RestFulRouterB struct { 10 | } 11 | 12 | // Equal is method to compare given num and slice sum 13 | func (r *RestFulRouterB) Get(context *restful.Context) { 14 | context.Write([]byte("version 1.1")) 15 | } 16 | 17 | // URLPatterns helps to respond for corresponding API calls 18 | func (r *RestFulRouterB) URLPatterns() []restful.Route { 19 | return []restful.Route{ 20 | {Method: http.MethodGet, Path: "/list", ResourceFuncName: "Get"}, 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /circuit/README.md: -------------------------------------------------------------------------------- 1 | # A circuit breaker example to show circuit breaker feature 2 | here is the config 3 | ```yaml 4 | --- 5 | --- 6 | cse: 7 | isolation: 8 | Consumer: 9 | timeoutInMilliseconds: 1000 10 | maxConcurrentRequests: 100 11 | circuitBreaker: 12 | Consumer: 13 | enabled: false 14 | forceOpen: false 15 | forceClosed: false 16 | sleepWindowInMilliseconds: 10000 17 | requestVolumeThreshold: 20 18 | errorThresholdPercentage: 1 19 | #容错处理函数,目前暂时按照开源的方式来不进行区分处理,统一调用fallback函数 20 | fallback: 21 | Consumer: 22 | enabled: true 23 | fallbackpolicy: 24 | Consumer: 25 | policy: throwexception 26 | ``` 27 | time out is 1000ms 28 | 29 | there is 3 APIs, 2 of them has different problem 30 | 31 | 1. client calls a API which has a dead lock, it will cause timout, so that circuit breaker will isolate this API 32 | 33 | 2. servcer has a lot of error response, circuit breaker will isolate this API 34 | 35 | in additinal, if client has a lot of concurrency, circuit breaker will isolate the API 36 | 37 | 38 | 39 | the runtime metrics is exported by prometheus exporter 40 | check 127.0.0.1:5000/metrics and 127.0.0.1:5001/metrics to observe services 41 | -------------------------------------------------------------------------------- /circuit/client/conf/chassis.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | cse: 3 | service: 4 | registry: 5 | address: http://127.0.0.1:30100 6 | handler: 7 | chain: 8 | Consumer: 9 | default: bizkeeper-consumer,loadbalance,transport 10 | transport: 11 | failure: 12 | rest: http_500,http_502 13 | protocols: 14 | rest: 15 | listenAddress: 127.0.0.1:5000 16 | advertiseAddress: 127.0.0.1:5000 -------------------------------------------------------------------------------- /circuit/client/conf/circuit_breaker.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | cse: 3 | isolation: 4 | Consumer: 5 | timeoutInMilliseconds: 1000 6 | maxConcurrentRequests: 3 7 | circuitBreaker: 8 | Consumer: 9 | enabled: true 10 | forceOpen: false 11 | forceClosed: false 12 | sleepWindowInMilliseconds: 10000 13 | requestVolumeThreshold: 10 14 | errorThresholdPercentage: 50 15 | #容错处理函数,目前暂时按照开源的方式来不进行区分处理,统一调用fallback函数 16 | fallback: 17 | Consumer: 18 | enabled: true 19 | fallbackpolicy: 20 | Consumer: 21 | policy: throwexception # if error happens, how to handle this error -------------------------------------------------------------------------------- /circuit/client/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | service_description: 3 | name: CircuitClient 4 | -------------------------------------------------------------------------------- /circuit/client/conf/monitoring.yaml: -------------------------------------------------------------------------------- 1 | cse: 2 | metrics: 3 | apiPath: /metrics # we can also give api path having prefix "/" ,like /adas/metrics 4 | enable: true 5 | enableGoRuntimeMetrics: true 6 | enableCircuitMetrics: true 7 | flushInterval: 10s 8 | tracing: 9 | tracer: zipkin 10 | settings: 11 | URI: http://127.0.0.1:9411/api/v1/spans 12 | batchSize: 1 13 | batchInterval: 1s -------------------------------------------------------------------------------- /circuit/client/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/go-chassis/go-chassis/v2" 5 | 6 | "context" 7 | 8 | _ "github.com/go-chassis/go-chassis/v2/bootstrap" 9 | "github.com/go-chassis/go-chassis/v2/client/rest" 10 | "github.com/go-chassis/go-chassis/v2/core" 11 | "github.com/go-chassis/go-chassis/v2/pkg/util/httputil" 12 | "github.com/go-chassis/openlog" 13 | "sync" 14 | ) 15 | 16 | //if you use go run main.go instead of binary run, plz export CHASSIS_HOME=/{path}/{to}/circuit/client/ 17 | func main() { 18 | //Init framework 19 | if err := chassis.Init(); err != nil { 20 | openlog.Error("Init failed." + err.Error()) 21 | return 22 | } 23 | for i := 0; i < 100; i++ { 24 | callError() 25 | } 26 | 27 | wg := &sync.WaitGroup{} 28 | for i := 0; i < 100; i++ { 29 | wg.Add(1) 30 | go callConcurrency(wg) 31 | } 32 | wg.Wait() 33 | for i := 0; i < 20; i++ { 34 | callDeadlock() 35 | } 36 | 37 | } 38 | func callError() { 39 | req, err := rest.NewRequest("GET", "http://CircuitServer/error", nil) 40 | if err != nil { 41 | openlog.GetLogger().Error("new request failed.") 42 | return 43 | } 44 | resp, err := core.NewRestInvoker().ContextDo(context.TODO(), req) 45 | if resp != nil { 46 | if resp.Body != nil { 47 | openlog.GetLogger().Info("response body: " + string(httputil.ReadBody(resp))) 48 | defer resp.Body.Close() 49 | } 50 | } 51 | 52 | if err != nil { 53 | openlog.GetLogger().Error("request failed: " + err.Error()) 54 | return 55 | } 56 | 57 | } 58 | func callConcurrency(wg *sync.WaitGroup) { 59 | defer wg.Done() 60 | req, err := rest.NewRequest("GET", "http://CircuitServer/concurrency", nil) 61 | if err != nil { 62 | openlog.Error("new request failed.") 63 | return 64 | } 65 | resp, err := core.NewRestInvoker().ContextDo(context.TODO(), req) 66 | if resp != nil { 67 | if resp.Body != nil { 68 | defer resp.Body.Close() 69 | openlog.GetLogger().Info("response body: " + string(httputil.ReadBody(resp))) 70 | } 71 | } 72 | if err != nil { 73 | openlog.GetLogger().Error("request failed: " + err.Error()) 74 | return 75 | } 76 | 77 | } 78 | func callDeadlock() { 79 | req, err := rest.NewRequest("GET", "http://CircuitServer/lock", nil) 80 | if err != nil { 81 | openlog.Error("new request failed.") 82 | return 83 | } 84 | resp, err := core.NewRestInvoker().ContextDo(context.TODO(), req) 85 | if resp != nil { 86 | if resp.Body != nil { 87 | defer resp.Body.Close() 88 | openlog.GetLogger().Info("response body: " + string(httputil.ReadBody(resp))) 89 | } 90 | } 91 | if err != nil { 92 | openlog.GetLogger().Error("request failed: " + err.Error()) 93 | return 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /circuit/server/conf/chassis.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | cse: 3 | service: 4 | registry: 5 | address: http://127.0.0.1:30100 6 | protocols: 7 | rest: 8 | listenAddress: 127.0.0.1:8081 9 | advertiseAddress: 127.0.0.1:8081 10 | -------------------------------------------------------------------------------- /circuit/server/conf/circuit_breaker.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | cse: 3 | isolation: 4 | Consumer: 5 | timeoutInMilliseconds: 1000 6 | maxConcurrentRequests: 100 7 | circuitBreaker: 8 | Consumer: 9 | enabled: false 10 | forceOpen: false 11 | forceClosed: false 12 | sleepWindowInMilliseconds: 10000 13 | requestVolumeThreshold: 20 14 | errorThresholdPercentage: 1 15 | #容错处理函数,目前暂时按照开源的方式来不进行区分处理,统一调用fallback函数 16 | fallback: 17 | Consumer: 18 | enabled: true 19 | fallbackpolicy: 20 | Consumer: 21 | policy: throwexception -------------------------------------------------------------------------------- /circuit/server/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | service_description: 3 | name: CircuitServer 4 | -------------------------------------------------------------------------------- /circuit/server/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/go-chassis/go-chassis-examples/circuit/server/resource" 5 | "github.com/go-chassis/go-chassis/v2" 6 | _ "github.com/go-chassis/go-chassis/v2/bootstrap" 7 | "github.com/go-chassis/openlog" 8 | ) 9 | 10 | //if you use go run main.go instead of binary run, plz export CHASSIS_HOME=/{path}/{to}/circuit/server/ 11 | func main() { 12 | chassis.RegisterSchema("rest", &resource.CircuitResource{}) 13 | //start all server you register in server/schemas. 14 | if err := chassis.Init(); err != nil { 15 | openlog.Error("Init failed." + err.Error()) 16 | return 17 | } 18 | chassis.Run() 19 | } 20 | -------------------------------------------------------------------------------- /circuit/server/resource/restful_hello.go: -------------------------------------------------------------------------------- 1 | package resource 2 | 3 | import ( 4 | "errors" 5 | "net/http" 6 | 7 | rf "github.com/go-chassis/go-chassis/v2/server/restful" 8 | "sync" 9 | ) 10 | 11 | //CircuitResource is a struct used for implementation of restful api 12 | type CircuitResource struct { 13 | lock sync.Mutex 14 | } 15 | 16 | //Sayerror is a method used to reply request user with error, it fulfills client side error threshold 17 | func (r *CircuitResource) GetError(b *rf.Context) { 18 | b.WriteError(http.StatusInternalServerError, errors.New("internal error")) 19 | return 20 | } 21 | 22 | //GetLock cause dead lock, it will cause client side timeout 23 | func (r *CircuitResource) GetLock(b *rf.Context) { 24 | r.lock.Lock() 25 | return 26 | } 27 | 28 | //MaxConcurrency is for MaxConcurrency test 29 | func (r *CircuitResource) MaxConcurrency(b *rf.Context) { 30 | b.WriteHeader(http.StatusOK) 31 | b.Write([]byte("too much concurrency")) 32 | return 33 | } 34 | 35 | //URLPatterns helps to respond for corresponding API calls 36 | func (r *CircuitResource) URLPatterns() []rf.Route { 37 | return []rf.Route{ 38 | {Method: http.MethodGet, Path: "/error", ResourceFuncName: "GetError"}, 39 | {Method: http.MethodGet, Path: "/lock", ResourceFuncName: "GetLock"}, 40 | {Method: http.MethodGet, Path: "/concurrency", ResourceFuncName: "MaxConcurrency"}, 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | services: 3 | sc: 4 | image: servicecomb/service-center:latest 5 | ports: 6 | - "30100:30100" 7 | zipkin: 8 | image: openzipkin/zipkin 9 | ports: 10 | - 9411:9411 11 | # prom: 12 | # command: "--config.file=/etc/prometheus/prometheus.yml" 13 | # image: quay.io/prometheus/prometheus:v2.0.0 14 | # volumes: 15 | # - ./prometheus.yml:/etc/prometheus/prometheus.yml 16 | # ports: 17 | # - 9090:9090 18 | # grafana: 19 | # image: grafana/grafana 20 | # ports: 21 | # - 3000:3000 22 | # links: 23 | # - prometheus 24 | # depends_on: 25 | # - prom -------------------------------------------------------------------------------- /eurekapp/README.md: -------------------------------------------------------------------------------- 1 | 2 | on linux 3 | 4 | ## run eureka server 5 | 6 | clone https://github.com/spring-cloud-samples/eureka and exec 7 | ``` bash 8 | ./gradlew build 9 | java -jar build/libs/eureka.jar 10 | ``` 11 | eureka server listen on http://127.0.0.1:8761 12 | 13 | ## run go chassis app with eureka plugin 14 | clone this sample and exec 15 | ```bash 16 | go mod tidy 17 | go build 18 | ./eurekapp 19 | ``` 20 | then visit http://127.0.0.1:8761 you can see EUREKAPP in "Instances currently registered with Eureka" 21 | -------------------------------------------------------------------------------- /eurekapp/conf/chassis.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | servicecomb: 3 | registry: 4 | disabled: false 5 | type: "eureka" 6 | address: http://127.0.0.1:8761/eureka/v2 7 | protocols: 8 | rest: 9 | listenAddress: 127.0.0.1:5001 10 | metrics: 11 | apiPath: /metrics # we can also give api path having prefix "/" ,like /adas/metrics 12 | enable: true 13 | enableGoRuntimeMetrics: true 14 | enableCircuitMetrics: true 15 | profile: 16 | enable: true 17 | apiPath: /profile -------------------------------------------------------------------------------- /eurekapp/conf/lager.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | logWriters: file,stdout 3 | # LoggerLevel: |DEBUG|INFO|WARN|ERROR|FATAL 4 | logLevel: DEBUG 5 | logFile: log/chassis.log 6 | logFormatText: false 7 | logRotateDisable: false 8 | #log rotate and backup settings 9 | logRotateAge: 1 # after n days 10 | logRotateSize: 10 # megabytes 11 | logBackupCount: 7 -------------------------------------------------------------------------------- /eurekapp/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | servicecomb: 2 | service: 3 | name: eurekapp 4 | -------------------------------------------------------------------------------- /eurekapp/controller/price.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "net/http" 5 | 6 | goRestful "github.com/emicklei/go-restful" 7 | rf "github.com/go-chassis/go-chassis/v2/server/restful" 8 | ) 9 | 10 | type Data struct { 11 | ID string `json:"priceID"` 12 | Category string `json:"type"` 13 | Value string `json:"value"` 14 | CreateTime string `json:"-"` 15 | err ErrorCode `json:"-"` 16 | } 17 | 18 | type ErrorCode struct { 19 | code uint32 20 | } 21 | 22 | type Result struct { 23 | Code ErrorCode 24 | Message string 25 | } 26 | 27 | func (d *Data) GetPrice(c *rf.Context) { 28 | var xx ErrorCode 29 | xx.code = 777 30 | x := &Data{ 31 | c.ReadPathParameter("id"), 32 | "internal", 33 | "104.5", 34 | "2019-09-09", 35 | xx, 36 | } 37 | c.WriteHeaderAndJSON(http.StatusOK, x, goRestful.MIME_JSON) 38 | } 39 | 40 | func (d *Data) URLPatterns() []rf.Route { 41 | 42 | return []rf.Route{ 43 | { 44 | Method: http.MethodGet, 45 | Path: "/price/{id}", 46 | ResourceFuncName: "GetPrice", 47 | Consumes: []string{goRestful.MIME_JSON, goRestful.MIME_XML}, 48 | Produces: []string{goRestful.MIME_JSON}, 49 | Returns: []*rf.Returns{{Code: http.StatusOK, Message: "true", Model: Data{}}}, 50 | Parameters: []*rf.Parameters{ 51 | {Name: "x-auth-token", DataType: "string", ParamType: goRestful.HeaderParameterKind, Desc: "this is a token", Required: true}, 52 | {Name: "x-auth-token2", DataType: "string", ParamType: goRestful.HeaderParameterKind, Desc: "this is a token", Required: true}, 53 | }, 54 | }, 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /eurekapp/go.mod: -------------------------------------------------------------------------------- 1 | module eurekapp 2 | 3 | go 1.17 4 | 5 | require ( 6 | gitee.com/daqingshu/eurekaplugin/v2 v2.0.2 7 | github.com/emicklei/go-restful v2.12.0+incompatible 8 | github.com/go-chassis/go-chassis/v2 v2.3.1-0.20211217084436-360a6a6a0ef3 9 | github.com/go-chassis/openlog v1.1.3 10 | ) 11 | 12 | require ( 13 | github.com/beorn7/perks v1.0.1 // indirect 14 | github.com/cenkalti/backoff v2.0.0+incompatible // indirect 15 | github.com/cenkalti/backoff/v4 v4.1.1 // indirect 16 | github.com/cespare/xxhash/v2 v2.1.1 // indirect 17 | github.com/daqingshu/go-eureka-client/eureka v0.0.0-20211231083947-bf48f8062e5d // indirect 18 | github.com/fsnotify/fsnotify v1.4.7 // indirect 19 | github.com/go-chassis/cari v0.5.1-0.20210823023004-74041d1363c4 // indirect 20 | github.com/go-chassis/foundation v0.3.0 // indirect 21 | github.com/go-chassis/go-archaius v1.5.1 // indirect 22 | github.com/go-chassis/go-restful-swagger20 v1.0.3 // indirect 23 | github.com/go-chassis/kie-client v0.0.0-20201210060018-938c7680a9ab // indirect 24 | github.com/go-chassis/sc-client v0.6.1-0.20210918130508-2b9daad232da // indirect 25 | github.com/go-chassis/seclog v1.3.1-0.20210917082355-52c40864f240 // indirect 26 | github.com/go-resty/resty/v2 v2.7.0 // indirect 27 | github.com/gogo/protobuf v1.3.1 // indirect 28 | github.com/golang/protobuf v1.4.3 // indirect 29 | github.com/gorilla/websocket v1.4.3-0.20210424162022-e8629af678b7 // indirect 30 | github.com/hashicorp/go-version v1.0.0 // indirect 31 | github.com/json-iterator/go v1.1.11 // indirect 32 | github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect 33 | github.com/miekg/dns v1.1.45 // indirect 34 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 35 | github.com/modern-go/reflect2 v1.0.1 // indirect 36 | github.com/opentracing/opentracing-go v1.1.0 // indirect 37 | github.com/patrickmn/go-cache v2.1.0+incompatible // indirect 38 | github.com/prometheus/client_golang v1.11.1 // indirect 39 | github.com/prometheus/client_model v0.2.0 // indirect 40 | github.com/prometheus/common v0.26.0 // indirect 41 | github.com/prometheus/procfs v0.6.0 // indirect 42 | github.com/spf13/cast v1.2.0 // indirect 43 | golang.org/x/mod v0.4.2 // indirect 44 | golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect 45 | golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect 46 | golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect 47 | golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2 // indirect 48 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect 49 | google.golang.org/protobuf v1.26.0-rc.1 // indirect 50 | gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect 51 | gopkg.in/yaml.v2 v2.4.0 // indirect 52 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect 53 | k8s.io/apimachinery v0.17.0 // indirect 54 | k8s.io/client-go v0.17.0 // indirect 55 | k8s.io/utils v0.0.0-20191114184206-e782cd3c129f // indirect 56 | ) 57 | -------------------------------------------------------------------------------- /eurekapp/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "eurekapp/controller" 5 | "eurekapp/router" 6 | 7 | "gitee.com/daqingshu/eurekaplugin/v2" 8 | "github.com/go-chassis/go-chassis/v2" 9 | "github.com/go-chassis/go-chassis/v2/core/server" 10 | "github.com/go-chassis/openlog" 11 | ) 12 | 13 | func main() { 14 | eurekaplugin.Init() 15 | chassis.RegisterSchema("rest", &controller.Data{}, server.WithSchemaID("PriceService")) 16 | chassis.RegisterSchema("rest", &router.RestFulRouterA{}, server.WithSchemaID("RestROUTERService")) 17 | if err := chassis.Init(); err != nil { 18 | openlog.Fatal("Init failed." + err.Error()) 19 | return 20 | } 21 | chassis.Run() 22 | } 23 | -------------------------------------------------------------------------------- /eurekapp/router/router.go: -------------------------------------------------------------------------------- 1 | package router 2 | 3 | import ( 4 | "net/http" 5 | 6 | "github.com/go-chassis/go-chassis/v2/server/restful" 7 | ) 8 | 9 | // RestFulRouterB is a struct used for implementation of restfull router program 10 | type RestFulRouterA struct { 11 | } 12 | 13 | // Equal is method to compare given num and slice product 14 | func (r *RestFulRouterA) Info(context *restful.Context) { 15 | versionInfo := struct { 16 | Name string `json:"name"` 17 | Version string `json:"version"` 18 | HostName string `json:"hostName"` 19 | }{ 20 | Name: "CHASSIS_SERVER_V1", 21 | Version: "1.0", 22 | HostName: context.ReadRequest().Host, 23 | } 24 | 25 | context.WriteJSON(versionInfo, "application/json") 26 | 27 | } 28 | 29 | // URLPatterns helps to respond for corresponding API calls 30 | func (r *RestFulRouterA) URLPatterns() []restful.Route { 31 | return []restful.Route{ 32 | {Method: http.MethodGet, Path: "/info", ResourceFunc: r.Info}, 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/go-chassis/go-chassis-examples 2 | 3 | require ( 4 | github.com/emicklei/go-restful v2.16.0+incompatible 5 | github.com/go-chassis/go-archaius v1.5.6 6 | github.com/go-chassis/go-chassis v1.8.3 7 | github.com/go-chassis/go-chassis-extension/protocol/fiber4r v0.0.0-20220815025917-8cf6a8451620 8 | github.com/go-chassis/go-chassis-extension/protocol/grpc v0.0.0-20220812101205-352f5742bee5 9 | github.com/go-chassis/go-chassis-extension/tracing/zipkin v0.0.0-20220812101205-352f5742bee5 10 | github.com/go-chassis/go-chassis/v2 v2.5.3-0.20220812094026-da04106bf75b 11 | github.com/go-chassis/openlog v1.1.3 12 | github.com/gofiber/fiber/v2 v2.36.0 13 | github.com/golang/protobuf v1.5.2 14 | golang.org/x/net v0.7.0 15 | google.golang.org/grpc v1.40.0 16 | ) 17 | 18 | go 1.16 19 | -------------------------------------------------------------------------------- /grace/README.md: -------------------------------------------------------------------------------- 1 | Graceful shutdown http server 2 | 3 | 1.Launch service center 4 | 5 | follow https://github.com/apache/servicecomb-service-center/tree/master/examples/infrastructures/docker 6 | 7 | 2.Run server 8 | 9 | ```sh 10 | cd server 11 | export CHASSIS_HOME=$PWD 12 | go run main.go 13 | 14 | ``` 15 | 16 | 3.Run client 17 | ```sh 18 | cd client 19 | export CHASSIS_HOME=$PWD 20 | go run main.go 21 | ``` 22 | 23 | server will wait 10 seconds to return a string "success", if you kill server before it response, 24 | the server will wait until all requests is finished. 25 | you will see success log 26 | 27 | INFO client/main.go:29 response body: success 28 | 29 | -------------------------------------------------------------------------------- /grace/client/conf/chassis.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | #APPLICATION_ID: CSE optional 3 | cse: 4 | service: 5 | registry: 6 | address: http://127.0.0.1:30100 7 | -------------------------------------------------------------------------------- /grace/client/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | #微服务的私有属性 3 | service_description: 4 | name: GraceClient -------------------------------------------------------------------------------- /grace/client/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "github.com/go-chassis/go-chassis/v2" 6 | _ "github.com/go-chassis/go-chassis/v2/bootstrap" 7 | "github.com/go-chassis/go-chassis/v2/client/rest" 8 | "github.com/go-chassis/go-chassis/v2/core" 9 | "github.com/go-chassis/go-chassis/v2/pkg/util/httputil" 10 | "github.com/go-chassis/openlog" 11 | ) 12 | 13 | //if you use go run main.go instead of binary run, plz export CHASSIS_HOME=/{path}/{to}/rest/client/ 14 | func main() { 15 | //Init framework 16 | if err := chassis.Init(); err != nil { 17 | openlog.Error("Init failed." + err.Error()) 18 | return 19 | } 20 | 21 | req, err := rest.NewRequest("GET", "http://GraceService/grace", nil) 22 | if err != nil { 23 | openlog.Error("new request failed.") 24 | return 25 | } 26 | resp, err := core.NewRestInvoker().ContextDo(context.TODO(), req) 27 | if resp != nil { 28 | if resp.Body != nil { 29 | openlog.GetLogger().Info("response body: " + string(httputil.ReadBody(resp))) 30 | defer resp.Body.Close() 31 | } 32 | } 33 | 34 | if err != nil { 35 | openlog.GetLogger().Error("request failed: " + err.Error()) 36 | return 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /grace/server/conf/chassis.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | cse: 3 | service: 4 | registry: 5 | address: http://127.0.0.1:30100 # If type is File then address will be the path of the file 6 | protocols: 7 | rest: 8 | listenAddress: "127.0.0.1:5001" 9 | #advertiseAddress: "internal_ip:5001" 10 | handler: 11 | chain: 12 | Provider: 13 | default: tracing-provider,bizkeeper-provider -------------------------------------------------------------------------------- /grace/server/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | #微服务的私有属性 3 | service_description: 4 | name: GraceService 5 | # status: TESTING -------------------------------------------------------------------------------- /grace/server/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/go-chassis/go-chassis-examples/grace/server/resource" 5 | "github.com/go-chassis/go-chassis/v2" 6 | "github.com/go-chassis/openlog" 7 | ) 8 | 9 | //if you use go run main.go instead of binary run, plz export CHASSIS_HOME=/{path}/{to}/rest/server/ 10 | 11 | func main() { 12 | chassis.RegisterSchema("rest", &resource.GraceResource{}) 13 | if err := chassis.Init(); err != nil { 14 | openlog.Error("Init failed." + err.Error()) 15 | return 16 | } 17 | chassis.Run() 18 | } 19 | -------------------------------------------------------------------------------- /grace/server/resource/restful_hello.go: -------------------------------------------------------------------------------- 1 | package resource 2 | 3 | import ( 4 | "net/http" 5 | 6 | rf "github.com/go-chassis/go-chassis/v2/server/restful" 7 | "time" 8 | ) 9 | 10 | //GraceResource is a struct used for implementation of restful api 11 | type GraceResource struct { 12 | } 13 | 14 | func (r *GraceResource) Wait(b *rf.Context) { 15 | time.Sleep(10 * time.Second) 16 | b.Write([]byte("success")) 17 | return 18 | } 19 | 20 | //URLPatterns helps to respond for corresponding API calls 21 | func (r *GraceResource) URLPatterns() []rf.Route { 22 | return []rf.Route{ 23 | {Method: http.MethodGet, Path: "/grace", ResourceFuncName: "Wait"}, 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /grpc/README.md: -------------------------------------------------------------------------------- 1 | # Quick start 2 | this example shows how grpc-go leverage go chassis to become a cloud native application 3 | 4 | 1. Launch service center 5 | 6 | 2. Run server 7 | 8 | ```sh 9 | cd examples/grpc/server 10 | export CHASSIS_HOME=$PWD 11 | go run main.go 12 | 13 | ``` 14 | 15 | 3. Run client 16 | ```sh 17 | cd examples/grpc/client 18 | export CHASSIS_HOME=$PWD 19 | go run main.go 20 | 21 | ``` -------------------------------------------------------------------------------- /grpc/bench/conf/chassis.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | cse: 3 | service: 4 | registry: 5 | address: http://127.0.0.1:30100 6 | handler: 7 | chain: 8 | Consumer: 9 | default: loadbalance,transport -------------------------------------------------------------------------------- /grpc/bench/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | #微服务的私有属性 3 | service_description: 4 | name: RPCClient -------------------------------------------------------------------------------- /grpc/bench/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "net/http" 6 | 7 | _ "net/http/pprof" 8 | "os" 9 | "sync" 10 | "time" 11 | 12 | "github.com/go-chassis/go-chassis-examples/grpc/helloworld" 13 | _ "github.com/go-chassis/go-chassis-extension/protocol/grpc/client" 14 | "github.com/go-chassis/go-chassis/v2" 15 | _ "github.com/go-chassis/go-chassis/v2/bootstrap" 16 | "github.com/go-chassis/go-chassis/v2/core" 17 | "github.com/go-chassis/openlog" 18 | "golang.org/x/net/context" 19 | "google.golang.org/grpc" 20 | ) 21 | 22 | var wg = sync.WaitGroup{} 23 | 24 | //if you use go run main.go instead of binary run, plz export CHASSIS_HOME=/{path}/{to}/grpc/client/ 25 | func main() { 26 | go func() { 27 | log.Println(http.ListenAndServe("localhost:6060", nil)) 28 | }() 29 | //Init framework 30 | if err := chassis.Init(); err != nil { 31 | openlog.Error("Init failed." + err.Error()) 32 | return 33 | } 34 | n := 1000000 35 | t := 10 36 | times := n / t 37 | 38 | for i := 0; i < t; i++ { 39 | wg.Add(1) 40 | go call(times) 41 | } 42 | wg.Wait() 43 | } 44 | 45 | func call(times int) { 46 | invoker := core.NewRPCInvoker() 47 | //declare reply struct 48 | for i := 0; i < times; i++ { 49 | reply := &helloworld.HelloReply{} 50 | ctx := context.Background() 51 | //Invoke with micro service name, schema ID and operation ID 52 | if err := invoker.Invoke(ctx, "RPCServer", 53 | "helloworld.Greeter", "SayHello", 54 | &helloworld.HelloRequest{Name: "Peter"}, reply, 55 | core.WithProtocol("grpc")); err != nil { 56 | openlog.Error("error" + err.Error()) 57 | } 58 | } 59 | //wg.Done() 60 | } 61 | func call2(times int) { 62 | conn, err := grpc.Dial("127.0.0.1:5000", grpc.WithInsecure()) 63 | if err != nil { 64 | log.Fatalf("did not connect: %v", err) 65 | } 66 | defer conn.Close() 67 | c := helloworld.NewGreeterClient(conn) 68 | 69 | // Contact the server and print out its response. 70 | name := "peter" 71 | if len(os.Args) > 1 { 72 | name = os.Args[1] 73 | } 74 | 75 | //declare reply struct 76 | for i := 0; i < times; i++ { 77 | ctx, _ := context.WithTimeout(context.Background(), time.Second) 78 | _, err := c.SayHello(ctx, &helloworld.HelloRequest{Name: name}) 79 | if err != nil { 80 | log.Fatalf("could not greet: %v", err) 81 | } 82 | } 83 | //wg.Done() 84 | } 85 | -------------------------------------------------------------------------------- /grpc/client/conf/chassis.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | cse: 3 | service: 4 | registry: 5 | address: http://127.0.0.1:30100 6 | -------------------------------------------------------------------------------- /grpc/client/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | #微服务的私有属性 3 | service_description: 4 | name: RPCClient -------------------------------------------------------------------------------- /grpc/client/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/go-chassis/go-chassis-examples/grpc/helloworld" 5 | _ "github.com/go-chassis/go-chassis-extension/protocol/grpc/client" 6 | "github.com/go-chassis/go-chassis/v2" 7 | _ "github.com/go-chassis/go-chassis/v2/bootstrap" 8 | "github.com/go-chassis/go-chassis/v2/core" 9 | "github.com/go-chassis/go-chassis/v2/core/common" 10 | "github.com/go-chassis/openlog" 11 | ) 12 | 13 | //if you use go run main.go instead of binary run, plz export CHASSIS_HOME=/{path}/{to}/grpc/client/ 14 | func main() { 15 | //Init framework 16 | if err := chassis.Init(); err != nil { 17 | openlog.Error("Init failed." + err.Error()) 18 | return 19 | } 20 | //declare reply struct 21 | reply := &helloworld.HelloReply{} 22 | //header will transport to target service 23 | ctx := common.NewContext(map[string]string{ 24 | "X-User": "pete", 25 | }) 26 | invoker := core.NewRPCInvoker() 27 | 28 | //Invoke with micro service name, schema ID and operation ID 29 | if err := invoker.Invoke(ctx, "RPCServer", "helloworld.Greeter", "SayHello", 30 | &helloworld.HelloRequest{Name: "Peter"}, reply, core.WithProtocol("grpc")); err != nil { 31 | openlog.Error("error" + err.Error()) 32 | } 33 | openlog.Info(reply.Message) 34 | } 35 | -------------------------------------------------------------------------------- /grpc/helloworld/helloworld.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. DO NOT EDIT. 2 | // source: helloworld.proto 3 | 4 | package helloworld 5 | 6 | import proto "github.com/golang/protobuf/proto" 7 | import fmt "fmt" 8 | import math "math" 9 | 10 | import ( 11 | context "golang.org/x/net/context" 12 | grpc "google.golang.org/grpc" 13 | ) 14 | 15 | // Reference imports to suppress errors if they are not otherwise used. 16 | var _ = proto.Marshal 17 | var _ = fmt.Errorf 18 | var _ = math.Inf 19 | 20 | // This is a compile-time assertion to ensure that this generated file 21 | // is compatible with the proto package it is being compiled against. 22 | // A compilation error at this line likely means your copy of the 23 | // proto package needs to be updated. 24 | const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package 25 | 26 | // The request message containing the user's name. 27 | type HelloRequest struct { 28 | Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` 29 | XXX_NoUnkeyedLiteral struct{} `json:"-"` 30 | XXX_unrecognized []byte `json:"-"` 31 | XXX_sizecache int32 `json:"-"` 32 | } 33 | 34 | func (m *HelloRequest) Reset() { *m = HelloRequest{} } 35 | func (m *HelloRequest) String() string { return proto.CompactTextString(m) } 36 | func (*HelloRequest) ProtoMessage() {} 37 | func (*HelloRequest) Descriptor() ([]byte, []int) { 38 | return fileDescriptor_helloworld_71e208cbdc16936b, []int{0} 39 | } 40 | func (m *HelloRequest) XXX_Unmarshal(b []byte) error { 41 | return xxx_messageInfo_HelloRequest.Unmarshal(m, b) 42 | } 43 | func (m *HelloRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { 44 | return xxx_messageInfo_HelloRequest.Marshal(b, m, deterministic) 45 | } 46 | func (dst *HelloRequest) XXX_Merge(src proto.Message) { 47 | xxx_messageInfo_HelloRequest.Merge(dst, src) 48 | } 49 | func (m *HelloRequest) XXX_Size() int { 50 | return xxx_messageInfo_HelloRequest.Size(m) 51 | } 52 | func (m *HelloRequest) XXX_DiscardUnknown() { 53 | xxx_messageInfo_HelloRequest.DiscardUnknown(m) 54 | } 55 | 56 | var xxx_messageInfo_HelloRequest proto.InternalMessageInfo 57 | 58 | func (m *HelloRequest) GetName() string { 59 | if m != nil { 60 | return m.Name 61 | } 62 | return "" 63 | } 64 | 65 | // The response message containing the greetings 66 | type HelloReply struct { 67 | Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` 68 | XXX_NoUnkeyedLiteral struct{} `json:"-"` 69 | XXX_unrecognized []byte `json:"-"` 70 | XXX_sizecache int32 `json:"-"` 71 | } 72 | 73 | func (m *HelloReply) Reset() { *m = HelloReply{} } 74 | func (m *HelloReply) String() string { return proto.CompactTextString(m) } 75 | func (*HelloReply) ProtoMessage() {} 76 | func (*HelloReply) Descriptor() ([]byte, []int) { 77 | return fileDescriptor_helloworld_71e208cbdc16936b, []int{1} 78 | } 79 | func (m *HelloReply) XXX_Unmarshal(b []byte) error { 80 | return xxx_messageInfo_HelloReply.Unmarshal(m, b) 81 | } 82 | func (m *HelloReply) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { 83 | return xxx_messageInfo_HelloReply.Marshal(b, m, deterministic) 84 | } 85 | func (dst *HelloReply) XXX_Merge(src proto.Message) { 86 | xxx_messageInfo_HelloReply.Merge(dst, src) 87 | } 88 | func (m *HelloReply) XXX_Size() int { 89 | return xxx_messageInfo_HelloReply.Size(m) 90 | } 91 | func (m *HelloReply) XXX_DiscardUnknown() { 92 | xxx_messageInfo_HelloReply.DiscardUnknown(m) 93 | } 94 | 95 | var xxx_messageInfo_HelloReply proto.InternalMessageInfo 96 | 97 | func (m *HelloReply) GetMessage() string { 98 | if m != nil { 99 | return m.Message 100 | } 101 | return "" 102 | } 103 | 104 | func init() { 105 | proto.RegisterType((*HelloRequest)(nil), "helloworld.HelloRequest") 106 | proto.RegisterType((*HelloReply)(nil), "helloworld.HelloReply") 107 | } 108 | 109 | // Reference imports to suppress errors if they are not otherwise used. 110 | var _ context.Context 111 | var _ grpc.ClientConn 112 | 113 | // This is a compile-time assertion to ensure that this generated file 114 | // is compatible with the grpc package it is being compiled against. 115 | const _ = grpc.SupportPackageIsVersion4 116 | 117 | // GreeterClient is the client API for Greeter service. 118 | // 119 | // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. 120 | type GreeterClient interface { 121 | // Sends a greeting 122 | SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error) 123 | } 124 | 125 | type greeterClient struct { 126 | cc *grpc.ClientConn 127 | } 128 | 129 | func NewGreeterClient(cc *grpc.ClientConn) GreeterClient { 130 | return &greeterClient{cc} 131 | } 132 | 133 | func (c *greeterClient) SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error) { 134 | out := new(HelloReply) 135 | err := c.cc.Invoke(ctx, "/helloworld.Greeter/SayHello", in, out, opts...) 136 | if err != nil { 137 | return nil, err 138 | } 139 | return out, nil 140 | } 141 | 142 | // GreeterServer is the server API for Greeter service. 143 | type GreeterServer interface { 144 | // Sends a greeting 145 | SayHello(context.Context, *HelloRequest) (*HelloReply, error) 146 | } 147 | 148 | func RegisterGreeterServer(s *grpc.Server, srv GreeterServer) { 149 | s.RegisterService(&Greeter_serviceDesc, srv) 150 | } 151 | 152 | func _Greeter_SayHello_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 153 | in := new(HelloRequest) 154 | if err := dec(in); err != nil { 155 | return nil, err 156 | } 157 | if interceptor == nil { 158 | return srv.(GreeterServer).SayHello(ctx, in) 159 | } 160 | info := &grpc.UnaryServerInfo{ 161 | Server: srv, 162 | FullMethod: "/helloworld.Greeter/SayHello", 163 | } 164 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 165 | return srv.(GreeterServer).SayHello(ctx, req.(*HelloRequest)) 166 | } 167 | return interceptor(ctx, in, info, handler) 168 | } 169 | 170 | var Greeter_serviceDesc = grpc.ServiceDesc{ 171 | ServiceName: "helloworld.Greeter", 172 | HandlerType: (*GreeterServer)(nil), 173 | Methods: []grpc.MethodDesc{ 174 | { 175 | MethodName: "SayHello", 176 | Handler: _Greeter_SayHello_Handler, 177 | }, 178 | }, 179 | Streams: []grpc.StreamDesc{}, 180 | Metadata: "helloworld.proto", 181 | } 182 | 183 | func init() { proto.RegisterFile("helloworld.proto", fileDescriptor_helloworld_71e208cbdc16936b) } 184 | 185 | var fileDescriptor_helloworld_71e208cbdc16936b = []byte{ 186 | // 175 bytes of a gzipped FileDescriptorProto 187 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0xc8, 0x48, 0xcd, 0xc9, 188 | 0xc9, 0x2f, 0xcf, 0x2f, 0xca, 0x49, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x42, 0x88, 189 | 0x28, 0x29, 0x71, 0xf1, 0x78, 0x80, 0x78, 0x41, 0xa9, 0x85, 0xa5, 0xa9, 0xc5, 0x25, 0x42, 0x42, 190 | 0x5c, 0x2c, 0x79, 0x89, 0xb9, 0xa9, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0x9c, 0x41, 0x60, 0xb6, 0x92, 191 | 0x1a, 0x17, 0x17, 0x54, 0x4d, 0x41, 0x4e, 0xa5, 0x90, 0x04, 0x17, 0x7b, 0x6e, 0x6a, 0x71, 0x71, 192 | 0x62, 0x3a, 0x4c, 0x11, 0x8c, 0x6b, 0xe4, 0xc9, 0xc5, 0xee, 0x5e, 0x94, 0x9a, 0x5a, 0x92, 0x5a, 193 | 0x24, 0x64, 0xc7, 0xc5, 0x11, 0x9c, 0x58, 0x09, 0xd6, 0x25, 0x24, 0xa1, 0x87, 0xe4, 0x02, 0x64, 194 | 0xcb, 0xa4, 0xc4, 0xb0, 0xc8, 0x14, 0xe4, 0x54, 0x2a, 0x31, 0x38, 0x19, 0x70, 0x49, 0x67, 0xe6, 195 | 0xeb, 0xa5, 0x17, 0x15, 0x24, 0xeb, 0xa5, 0x56, 0x24, 0xe6, 0x16, 0xe4, 0xa4, 0x16, 0x23, 0xa9, 196 | 0x75, 0xe2, 0x07, 0x2b, 0x0e, 0x07, 0xb1, 0x03, 0x40, 0x5e, 0x0a, 0x60, 0x4c, 0x62, 0x03, 0xfb, 197 | 0xcd, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0x0f, 0xb7, 0xcd, 0xf2, 0xef, 0x00, 0x00, 0x00, 198 | } 199 | -------------------------------------------------------------------------------- /grpc/helloworld/helloworld.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2015 gRPC authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | option java_multiple_files = true; 18 | option java_package = "io.grpc.examples.helloworld"; 19 | option java_outer_classname = "HelloWorldProto"; 20 | 21 | package helloworld; 22 | 23 | // The greeting service definition. 24 | service Greeter { 25 | // Sends a greeting 26 | rpc SayHello (HelloRequest) returns (HelloReply) {} 27 | } 28 | 29 | // The request message containing the user's name. 30 | message HelloRequest { 31 | string name = 1; 32 | } 33 | 34 | // The response message containing the greetings 35 | message HelloReply { 36 | string message = 1; 37 | } 38 | -------------------------------------------------------------------------------- /grpc/server/conf/chassis.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | cse: 3 | service: 4 | registry: 5 | address: http://127.0.0.1:30100 # If type is File then address will be the path of the file 6 | protocols: 7 | grpc: 8 | listenAddress: 127.0.0.1:5000 9 | advertiseAddress: 127.0.0.1:5000 -------------------------------------------------------------------------------- /grpc/server/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | #微服务的私有属性 3 | service_description: 4 | name: RPCServer -------------------------------------------------------------------------------- /grpc/server/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | pb "github.com/go-chassis/go-chassis-examples/grpc/helloworld" 5 | _ "github.com/go-chassis/go-chassis-extension/protocol/grpc/server" 6 | "github.com/go-chassis/go-chassis/v2" 7 | "github.com/go-chassis/go-chassis/v2/core/server" 8 | "github.com/go-chassis/openlog" 9 | "golang.org/x/net/context" 10 | "google.golang.org/grpc/metadata" 11 | "log" 12 | ) 13 | 14 | //if you use go run main.go instead of binary run, plz export CHASSIS_HOME=/{path}/{to}/grpc/server/ 15 | // Server is used to implement helloworld.GreeterServer. 16 | type Server struct{} 17 | 18 | // SayHello implements helloworld.GreeterServer 19 | func (s *Server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) { 20 | md, _ := metadata.FromIncomingContext(ctx) 21 | log.Println(md["x-user"]) 22 | return &pb.HelloReply{Message: "Hello " + in.Name}, nil 23 | } 24 | func main() { 25 | chassis.RegisterSchema("grpc", &Server{}, server.WithRPCServiceDesc(&pb.Greeter_serviceDesc)) 26 | if err := chassis.Init(); err != nil { 27 | openlog.Error("Init failed.") 28 | return 29 | } 30 | chassis.Run() 31 | } 32 | -------------------------------------------------------------------------------- /hello/client/conf/chassis.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | servicecomb: 3 | registry: 4 | address: http://127.0.0.1:30100 5 | protocols: 6 | rest: 7 | listenAddress: 127.0.0.1:8000 -------------------------------------------------------------------------------- /hello/client/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | servicecomb: 2 | service: 3 | name: HelloClient -------------------------------------------------------------------------------- /hello/client/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "log" 6 | "net/http" 7 | 8 | "github.com/go-chassis/go-chassis/v2" 9 | "github.com/go-chassis/go-chassis/v2/client/rest" 10 | "github.com/go-chassis/go-chassis/v2/core" 11 | "github.com/go-chassis/go-chassis/v2/pkg/util/httputil" 12 | rf "github.com/go-chassis/go-chassis/v2/server/restful" 13 | "github.com/go-chassis/openlog" 14 | ) 15 | 16 | type SimpleResource struct { 17 | } 18 | 19 | func (r *SimpleResource) SayHi(b *rf.Context) { 20 | req, _ := rest.NewRequest(http.MethodGet, "http://HelloServer/hello", nil) 21 | restInvoker := core.NewRestInvoker() 22 | resp, err := restInvoker.ContextDo(context.TODO(), req) 23 | if err != nil { 24 | log.Println(err) 25 | return 26 | } 27 | b.Write(httputil.ReadBody(resp)) 28 | return 29 | } 30 | 31 | func (r *SimpleResource) URLPatterns() []rf.Route { 32 | return []rf.Route{ 33 | {Method: http.MethodGet, Path: "/hi", ResourceFunc: r.SayHi}, 34 | } 35 | } 36 | 37 | //if you use go run main.go instead of binary run, plz export CHASSIS_HOME=/{path}/{to}/server/ 38 | 39 | func main() { 40 | chassis.RegisterSchema("rest", &SimpleResource{}) 41 | if err := chassis.Init(); err != nil { 42 | openlog.Fatal("Init failed." + err.Error()) 43 | return 44 | } 45 | chassis.Run() 46 | } 47 | -------------------------------------------------------------------------------- /hello/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/go-chassis/go-chassis-examples/hello 2 | 3 | go 1.13 4 | 5 | require ( 6 | github.com/go-chassis/go-chassis/v2 v2.5.2 7 | github.com/go-chassis/openlog v1.1.2 8 | ) 9 | -------------------------------------------------------------------------------- /hello/server/conf/chassis.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | servicecomb: 3 | registry: 4 | address: http://127.0.0.1:30100 5 | protocols: 6 | rest: 7 | listenAddress: 127.0.0.1:9000 -------------------------------------------------------------------------------- /hello/server/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | servicecomb: 2 | service: 3 | name: HelloServer -------------------------------------------------------------------------------- /hello/server/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/go-chassis/go-chassis/v2" 5 | rf "github.com/go-chassis/go-chassis/v2/server/restful" 6 | "github.com/go-chassis/openlog" 7 | "net/http" 8 | ) 9 | 10 | type HelloResource struct { 11 | } 12 | 13 | func (r *HelloResource) SayHi(b *rf.Context) { 14 | b.Write([]byte("hello. go chassis")) 15 | return 16 | } 17 | 18 | func (r *HelloResource) URLPatterns() []rf.Route { 19 | return []rf.Route{ 20 | {Method: http.MethodGet, Path: "/hello", ResourceFunc: r.SayHi}, 21 | } 22 | } 23 | 24 | //if you use go run main.go instead of binary run, plz export CHASSIS_HOME=/{path}/{to}/server/ 25 | 26 | func main() { 27 | chassis.RegisterSchema("rest", &HelloResource{}) 28 | if err := chassis.Init(); err != nil { 29 | openlog.Fatal("Init failed." + err.Error()) 30 | return 31 | } 32 | chassis.Run() 33 | } 34 | -------------------------------------------------------------------------------- /java-call-go/README.md: -------------------------------------------------------------------------------- 1 | This demo as an example of how to go as a provider, java as consumers 2 | 3 | 1.Install [service-center](http://servicecomb.apache.org/release/) 4 | 5 | 2.run the price service 6 | 7 | ```shell 8 | cd go-chassis-examples/java-call-go/price 9 | export CHASSIS_HOME=$PWD 10 | go run main.go 11 | ``` 12 | 3.run the order service. 13 | ```shell 14 | mvn clean install 15 | mvn spring-boot:run 16 | ``` 17 | Or run in the IDE main function 18 | 19 | go-chassis-examples/java-call-go/order/src/main/java/com/xxx/order/Application.java 20 | 21 | 4.open http://127.0.0.1:9081/order/1101 test and verify results -------------------------------------------------------------------------------- /java-call-go/order/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.xxx 8 | order 9 | 0.0.1 10 | 11 | 12 | 13 | org.apache.servicecomb 14 | java-chassis-dependencies 15 | 1.2.0 16 | pom 17 | import 18 | 19 | 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter 25 | 26 | 27 | org.apache.servicecomb 28 | spring-boot-starter-provider 29 | 30 | 31 | org.hibernate 32 | hibernate-validator 33 | 34 | 35 | -------------------------------------------------------------------------------- /java-call-go/order/src/main/java/com/xxx/order/Application.java: -------------------------------------------------------------------------------- 1 | package com.xxx.order; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.apache.servicecomb.springboot.starter.provider.EnableServiceComb; 6 | 7 | @SpringBootApplication 8 | @EnableServiceComb 9 | public class Application { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(Application.class, args); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /java-call-go/order/src/main/java/com/xxx/order/Data.java: -------------------------------------------------------------------------------- 1 | package com.xxx.order; 2 | 3 | public class Data { 4 | private String priceID; 5 | 6 | public String getPriceID() { 7 | return priceID; 8 | } 9 | 10 | public void setPriceID(String priceID) { 11 | this.priceID = priceID; 12 | } 13 | 14 | private String type; 15 | 16 | public String getType() { 17 | return type; 18 | } 19 | 20 | public void setType(String type) { 21 | this.type = type; 22 | } 23 | 24 | public String getValue() { 25 | return value; 26 | } 27 | 28 | public void setValue(String value) { 29 | this.value = value; 30 | } 31 | 32 | private String value; 33 | //private ErrorCode 34 | } 35 | -------------------------------------------------------------------------------- /java-call-go/order/src/main/java/com/xxx/order/ErrorCode.java: -------------------------------------------------------------------------------- 1 | package com.xxx.order; 2 | 3 | public class ErrorCode { 4 | private long code; 5 | 6 | public long getCode() { 7 | return code; 8 | } 9 | 10 | public void setCode(long code) { 11 | this.code = code; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /java-call-go/order/src/main/java/com/xxx/order/OrderController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package com.xxx.order; 19 | 20 | import org.apache.servicecomb.provider.rest.common.RestSchema; 21 | import org.springframework.beans.factory.annotation.Autowired; 22 | import org.springframework.web.bind.annotation.GetMapping; 23 | import org.springframework.web.bind.annotation.PathVariable; 24 | import org.springframework.web.bind.annotation.RequestMapping; 25 | 26 | @RestSchema(schemaId = "order") 27 | @RequestMapping(path = "/") 28 | public class OrderController { 29 | 30 | @Autowired 31 | private OrderService orderService; 32 | 33 | @GetMapping(path = "/order/{id}") 34 | public Data getOrder(@PathVariable(name = "id") String id) { 35 | Data data = orderService.getPrice(id); 36 | return data; 37 | } 38 | } -------------------------------------------------------------------------------- /java-call-go/order/src/main/java/com/xxx/order/OrderService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package com.xxx.order; 19 | 20 | import javax.ws.rs.GET; 21 | import javax.ws.rs.Path; 22 | 23 | import org.apache.servicecomb.provider.springmvc.reference.CseRestTemplate; 24 | import org.springframework.stereotype.Component; 25 | 26 | @Component 27 | public class OrderService { 28 | 29 | private final CseRestTemplate restTemplate = new CseRestTemplate(); 30 | 31 | public Data getPrice(String id) { 32 | //service url is : cse://serviceName/operation 33 | String serviceName = "PriceServer"; 34 | Data result = restTemplate.getForObject("rest://" + serviceName + "/price/"+id, Data.class); 35 | return result; 36 | } 37 | } -------------------------------------------------------------------------------- /java-call-go/order/src/main/resources/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Main-Class: com.xxx.order.Application 2 | -------------------------------------------------------------------------------- /java-call-go/order/src/main/resources/microservice.yaml: -------------------------------------------------------------------------------- 1 | APPLICATION_ID: default 2 | service_description: 3 | name: orderService 4 | version: 0.0.1 5 | servicecomb: 6 | handler: 7 | chain: 8 | Provider: {} 9 | highway: 10 | address: 0.0.0.0:9091 11 | rest: 12 | address: 0.0.0.0:9081 13 | service: 14 | registry: 15 | address: http://localhost:30100 16 | autodiscovery: false 17 | # other configurations omitted 18 | references: 19 | PriceServer: 20 | version-rule: 0.0.1 21 | transport: rest -------------------------------------------------------------------------------- /java-call-go/price/conf/PriceServer/schema/PriceServer.yaml: -------------------------------------------------------------------------------- 1 | swagger: "2.0" 2 | info: 3 | title: "" 4 | version: "" 5 | x-java-interface: "com.xxx.order.Data" 6 | basePath: / 7 | paths: 8 | /price/{id}: 9 | get: 10 | operationId: GetPrice 11 | parameters: 12 | - name: x-auth-token 13 | in: header 14 | description: this is a token 15 | type: string 16 | - name: x-auth-token2 17 | in: header 18 | description: this is a token 19 | type: string 20 | consumes: 21 | - application/json 22 | - application/xml 23 | produces: 24 | - application/json 25 | responses: 26 | "200": 27 | description: "true" 28 | schema: 29 | $ref: '#/definitions/Data' 30 | definitions: 31 | Data: 32 | type: object 33 | properties: 34 | priceID: 35 | type: string 36 | type: 37 | type: string 38 | value: 39 | type: string 40 | -------------------------------------------------------------------------------- /java-call-go/price/conf/chassis.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | cse: 3 | service: 4 | registry: 5 | address: http://127.0.0.1:30100 # If type is File then address will be the path of the file 6 | protocols: 7 | rest: 8 | listenAddress: "127.0.0.1:5003" 9 | noRefreshSchema: true -------------------------------------------------------------------------------- /java-call-go/price/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | service_description: 3 | name: PriceServer 4 | -------------------------------------------------------------------------------- /java-call-go/price/controller/price.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | goRestful "github.com/emicklei/go-restful" 5 | rf "github.com/go-chassis/go-chassis/v2/server/restful" 6 | "net/http" 7 | ) 8 | 9 | type Data struct { 10 | ID string `json:"priceID"` 11 | Category string `json:"type"` 12 | Value string `json:"value"` 13 | CreateTime string `json:"-"` 14 | err ErrorCode `json:"-"` 15 | } 16 | 17 | type ErrorCode struct { 18 | code uint32 19 | } 20 | 21 | type Result struct { 22 | Code ErrorCode 23 | Message string 24 | } 25 | 26 | func (d *Data) GetPrice(c *rf.Context) { 27 | var xx ErrorCode 28 | xx.code = 777 29 | x := &Data{ 30 | c.ReadPathParameter("id"), 31 | "internal", 32 | "104.5", 33 | "2019-09-09", 34 | xx, 35 | } 36 | c.WriteHeaderAndJSON(http.StatusOK, x, goRestful.MIME_JSON) 37 | } 38 | 39 | func (d *Data) URLPatterns() []rf.Route { 40 | 41 | return []rf.Route{ 42 | { 43 | Method: http.MethodGet, 44 | Path: "/price/{id}", 45 | ResourceFuncName: "GetPrice", 46 | Consumes: []string{goRestful.MIME_JSON, goRestful.MIME_XML}, 47 | Produces: []string{goRestful.MIME_JSON}, 48 | Returns: []*rf.Returns{{Code: http.StatusOK, Message: "true", Model: Data{}}}, 49 | Parameters: []*rf.Parameters{ 50 | &rf.Parameters{"x-auth-token", "string", goRestful.HeaderParameterKind, "this is a token"}, 51 | &rf.Parameters{"x-auth-token2", "string", goRestful.HeaderParameterKind, "this is a token"}, 52 | }, 53 | }, 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /java-call-go/price/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/go-chassis/go-chassis-examples/java-call-go/price/controller" 5 | "github.com/go-chassis/go-chassis/v2" 6 | "github.com/go-chassis/go-chassis/v2/core/lager" 7 | "github.com/go-chassis/go-chassis/v2/core/server" 8 | ) 9 | 10 | func main() { 11 | chassis.RegisterSchema("rest", &controller.Data{}, server.WithSchemaID("PriceService")) 12 | if err := chassis.Init(); err != nil { 13 | lager.Logger.Error("Init failed." + err.Error()) 14 | return 15 | } 16 | chassis.Run() 17 | } 18 | -------------------------------------------------------------------------------- /metrics/README.md: -------------------------------------------------------------------------------- 1 | # Quik start with examples 2 | 3 | 1. Launch service center 4 | ```sh 5 | cd examples 6 | docker-compose up 7 | ``` 8 | 9 | 2. Run rest server 10 | 11 | ```sh 12 | cd server 13 | export CHASSIS_HOME=$PWD 14 | go run main.go 15 | 16 | ``` 17 | 18 | 3. call api `/login` or `sign_out` 19 | api of `/login` is `POST` , `sign_out` is `GET` 20 | 21 | call `http://127.0.0.1:8080/login` , the data of body 22 | ```json 23 | { 24 | "user_name":"user_test", 25 | "sex":"male", 26 | "age":27, 27 | "pwd":"123456" 28 | } 29 | ``` 30 | will reply : 31 | ```json 32 | { 33 | "user_name": "user_test", 34 | "sex": "male", 35 | "age": 27 36 | } 37 | ``` 38 | 4. get metrics data 39 | if you successful access the api `/login` , then you access `http://127.0.0.1:8080/metrics ` , 40 | in the return content you can see the following 41 | ```text 42 | # HELP login_total count user login 43 | # TYPE login_total counter 44 | login_total{username="user_test login"} 1 45 | ``` 46 | 5. [metrics](https://docs.go-chassis.com/user-guides/metrics.html) API 47 | 48 | before you use metrics api of go-chassis , you need use `metrics.Init()` init metrics 49 | 50 | ##### create counter 51 | 52 | ```go 53 | metrics.CreateCounter(metrics.CounterOpts{ 54 | Help: "count user login", 55 | Name: "login_total", 56 | Labels: []string{"username"}}) 57 | ``` 58 | 59 | add data into metrics 60 | ```go 61 | metrics.CounterAdd("sign_out_total", 1, map[string]string{"username": fmt.Sprintf("%s sign out", "user_test")}) 62 | ``` 63 | 64 | -------------------------------------------------------------------------------- /metrics/server/conf/auth.yaml: -------------------------------------------------------------------------------- 1 | cse: 2 | credentials: 3 | accessKey: 4 | secretKey: 5 | project: 6 | akskCustomCipher: default -------------------------------------------------------------------------------- /metrics/server/conf/chassis.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | cse: 3 | service: 4 | registry: 5 | type: servicecenter 6 | scope: full 7 | refreshInterval : 10s 8 | address: http://127.0.0.1:30100 9 | # address: https://cse.cn-north-1.myhuaweicloud.com 10 | refeshInterval : 1 11 | watch: true 12 | protocols: 13 | rest: 14 | listenAddress: 127.0.0.1:8080 15 | advertiseAddress: 127.0.0.1:8080 16 | handler: 17 | chain: 18 | Provider: 19 | incoming: ratelimiter-provider,tracing-provider,bizkeeper-provider 20 | metrics: 21 | apiPath: /metrics # we can also give api path having prefix "/" ,like /adas/metrics 22 | enable: true 23 | enableGoRuntimeMetrics: true 24 | enableCircuitMetrics: true -------------------------------------------------------------------------------- /metrics/server/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | #微服务的私有属性 3 | service_description: 4 | name: RESTSServer -------------------------------------------------------------------------------- /metrics/server/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/go-chassis/go-chassis-examples/metrics/server/schema" 5 | "github.com/go-chassis/go-chassis/v2" 6 | "github.com/go-chassis/go-chassis/v2/core/server" 7 | "github.com/go-chassis/go-chassis/v2/pkg/metrics" 8 | "github.com/go-chassis/openlog" 9 | ) 10 | 11 | func main() { 12 | chassis.RegisterSchema("rest", &schema.User{}, server.WithSchemaID("server")) 13 | err := chassis.Init() 14 | if err != nil { 15 | openlog.Error("chassis init failed ,err: " + err.Error()) 16 | } 17 | metrics.CreateCounter(metrics.CounterOpts{ 18 | Help: "count user login", 19 | Name: schema.Login, 20 | Labels: []string{schema.Label}}) 21 | metrics.CreateCounter(metrics.CounterOpts{ 22 | Help: "user sign out", 23 | Name: schema.SignOut, 24 | Labels: []string{schema.Label}}) 25 | chassis.Run() 26 | } 27 | -------------------------------------------------------------------------------- /metrics/server/schema/schema.go: -------------------------------------------------------------------------------- 1 | package schema 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "net/http" 7 | 8 | "github.com/go-chassis/go-chassis/v2/pkg/metrics" 9 | "github.com/go-chassis/go-chassis/v2/server/restful" 10 | ) 11 | 12 | type User struct { 13 | UserName string `json:"user_name"` 14 | Sex string `json:"sex"` 15 | Age int `json:"age"` 16 | Pwd string `json:"-"` 17 | } 18 | 19 | var userLogin = make(map[string]*User) 20 | 21 | func (u *User) Login(ctx *restful.Context) { 22 | ctx.ReadEntity(u) 23 | if _, ok := userLogin[u.UserName]; ok { 24 | metrics.CounterAdd(Login, 1, map[string]string{Label: fmt.Sprintf("%s Login failed , %[1]s repeat Login", u.UserName)}) 25 | ctx.Write([]byte(u.UserName + " aAlready landing , do not Login agent")) 26 | return 27 | } 28 | userLogin[u.UserName] = u 29 | metrics.CounterAdd(Login, 1, map[string]string{Label: fmt.Sprintf("%s Login", u.UserName)}) 30 | b, _ := json.Marshal(u) 31 | ctx.Write(b) 32 | } 33 | 34 | func (*User) SignOut(ctx *restful.Context) { 35 | user := ctx.ReadQueryParameter("user_name") 36 | if _, ok := userLogin[user]; !ok { 37 | metrics.CounterAdd(SignOut, 1, map[string]string{Label: fmt.Sprintf("%s sign out failed , %[1]s not Login", user)}) 38 | ctx.Write([]byte(user + " not Login , did not need sign out")) 39 | return 40 | } 41 | delete(userLogin, user) 42 | metrics.CounterAdd(SignOut, 1, map[string]string{Label: fmt.Sprintf("%s sign out", user)}) 43 | ctx.Write([]byte(user + " sing out success")) 44 | } 45 | 46 | //URLPatterns helps to respond for corresponding API calls 47 | func (*User) URLPatterns() []restful.Route { 48 | return []restful.Route{ 49 | {Method: http.MethodPost, Path: "/Login", ResourceFuncName: "Login"}, 50 | {Method: http.MethodGet, Path: "/sign_out", ResourceFuncName: "SignOut"}, 51 | } 52 | } 53 | 54 | const ( 55 | Login = "login_total" 56 | SignOut = "sign_out_total" 57 | Label = "username" 58 | ) 59 | 60 | func init() { 61 | 62 | } 63 | -------------------------------------------------------------------------------- /monitoring/README.md: -------------------------------------------------------------------------------- 1 | # Quik start with examples 2 | 3 | 1. Launch service center 4 | ```sh 5 | cd examples 6 | docker-compose up 7 | ``` 8 | 9 | 2. Run rest server 10 | 11 | ```sh 12 | cd serverA 13 | export CHASSIS_HOME=$PWD 14 | go run main.go 15 | 16 | ``` 17 | ```sh 18 | cd serverB 19 | export CHASSIS_HOME=$PWD 20 | go run main.go 21 | 22 | ``` 23 | 3. Run rest client 24 | ```sh 25 | cd client 26 | export CHASSIS_HOME=$PWD 27 | go run main.go 28 | 29 | ``` 30 | 31 | 4. check zikpin at http://127.0.0.1:9411 32 | 33 | 5. check metrics at http://127.0.0.1:5001 34 | 35 | 36 | -------------------------------------------------------------------------------- /monitoring/client/conf/chassis.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | #APPLICATION_ID: CSE optional 3 | cse: 4 | service: 5 | registry: 6 | address: http://127.0.0.1:30100 7 | handler: 8 | chain: 9 | Consumer: 10 | default: bizkeeper-consumer,router,loadbalance,tracing-consumer,transport -------------------------------------------------------------------------------- /monitoring/client/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | #微服务的私有属性 3 | service_description: 4 | name: RESTClient -------------------------------------------------------------------------------- /monitoring/client/conf/monitoring.yaml: -------------------------------------------------------------------------------- 1 | cse: 2 | metrics: 3 | apiPath: /metrics # we can also give api path having prefix "/" ,like /someurl/metrics 4 | enable: true 5 | enableGoRuntimeMetrics: true 6 | flushInterval: 10s 7 | tracing: 8 | tracer: zipkin 9 | settings: 10 | collector: http 11 | URI: http://127.0.0.1:9411/api/v1/spans 12 | batchSize: 1 13 | batchInterval: 1s -------------------------------------------------------------------------------- /monitoring/client/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "github.com/go-chassis/openlog" 6 | 7 | _ "github.com/go-chassis/go-chassis-extension/tracing/zipkin" 8 | "github.com/go-chassis/go-chassis/v2" 9 | _ "github.com/go-chassis/go-chassis/v2/bootstrap" 10 | "github.com/go-chassis/go-chassis/v2/client/rest" 11 | "github.com/go-chassis/go-chassis/v2/core" 12 | "github.com/go-chassis/go-chassis/v2/pkg/util/httputil" 13 | "time" 14 | ) 15 | 16 | //if you use go run main.go instead of binary run, plz export CHASSIS_HOME=/{path}/{to}/client/ 17 | func main() { 18 | //Init framework 19 | if err := chassis.Init(); err != nil { 20 | openlog.Error("Init failed." + err.Error()) 21 | return 22 | } 23 | 24 | req, err := rest.NewRequest("GET", "http://RESTServerA/trace", nil) 25 | if err != nil { 26 | openlog.Error("new request failed." + err.Error()) 27 | return 28 | } 29 | 30 | resp, err := core.NewRestInvoker().ContextDo(context.TODO(), req) 31 | if err != nil { 32 | openlog.Error("do request failed." + err.Error()) 33 | return 34 | } 35 | defer resp.Body.Close() 36 | openlog.Info("REST Server sayhello[GET]: " + string(httputil.ReadBody(resp))) 37 | time.Sleep(2 * time.Second) 38 | } 39 | -------------------------------------------------------------------------------- /monitoring/serverA/conf/chassis.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | cse: 3 | service: 4 | registry: 5 | address: http://127.0.0.1:30100 # If type is File then address will be the path of the file 6 | protocols: 7 | rest: 8 | listenAddress: 127.0.0.1:5001 9 | advertiseAddress: 127.0.0.1:5001 -------------------------------------------------------------------------------- /monitoring/serverA/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | #微服务的私有属性 3 | service_description: 4 | name: RESTServerA -------------------------------------------------------------------------------- /monitoring/serverA/conf/monitoring.yaml: -------------------------------------------------------------------------------- 1 | cse: 2 | metrics: 3 | apiPath: /metrics # we can also give api path having prefix "/" ,like /adas/metrics 4 | enable: true 5 | enableGoRuntimeMetrics: true 6 | flushInterval: 10s 7 | tracing: 8 | tracer: zipkin 9 | settings: 10 | URI: http://127.0.0.1:9411/api/v1/spans 11 | batchSize: 1 12 | batchInterval: 1s -------------------------------------------------------------------------------- /monitoring/serverA/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/go-chassis/go-chassis/v2" 5 | "github.com/go-chassis/go-chassis/v2/core/server" 6 | "github.com/go-chassis/go-chassis/v2/examples/schemas" 7 | "github.com/go-chassis/openlog" 8 | 9 | //tracers 10 | _ "github.com/go-chassis/go-chassis-extension/tracing/zipkin" 11 | ) 12 | 13 | //if you use go run main.go instead of binary run, plz export CHASSIS_HOME=/{path}/{to}/serverA/ 14 | 15 | func main() { 16 | chassis.RegisterSchema("rest", &schemas.TracingHello{}, server.WithSchemaID("TracingHello")) 17 | if err := chassis.Init(); err != nil { 18 | openlog.Error("Init failed." + err.Error()) 19 | return 20 | } 21 | chassis.Run() 22 | } 23 | -------------------------------------------------------------------------------- /monitoring/serverB/conf/chassis.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | cse: 3 | service: 4 | registry: 5 | address: http://127.0.0.1:30100 # If type is File then address will be the path of the file 6 | protocols: 7 | rest: 8 | listenAddress: 127.0.0.1:5002 9 | advertiseAddress: 127.0.0.1:5002 -------------------------------------------------------------------------------- /monitoring/serverB/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | #微服务的私有属性 3 | service_description: 4 | name: RESTServerB -------------------------------------------------------------------------------- /monitoring/serverB/conf/monitoring.yaml: -------------------------------------------------------------------------------- 1 | cse: 2 | metrics: 3 | apiPath: /metrics # we can also give api path having prefix "/" ,like /adas/metrics 4 | enable: true 5 | enableGoRuntimeMetrics: true 6 | flushInterval: 10s 7 | tracing: 8 | tracer: zipkin 9 | settings: 10 | URI: http://127.0.0.1:9411/api/v1/spans 11 | batchSize: 1 12 | batchInterval: 1s -------------------------------------------------------------------------------- /monitoring/serverB/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | //tracers 5 | _ "github.com/go-chassis/go-chassis-extension/tracing/zipkin" 6 | 7 | "github.com/go-chassis/go-chassis/v2" 8 | "github.com/go-chassis/go-chassis/v2/core/server" 9 | "github.com/go-chassis/go-chassis/v2/examples/schemas" 10 | "github.com/go-chassis/openlog" 11 | ) 12 | 13 | //if you use go run main.go instead of binary run, plz export CHASSIS_HOME=/{path}/{to}/serverB/ 14 | 15 | func main() { 16 | chassis.RegisterSchema("rest", &schemas.RestFulHello{}, server.WithSchemaID("RestHelloService")) 17 | if err := chassis.Init(); err != nil { 18 | openlog.Error("Init failed." + err.Error()) 19 | return 20 | } 21 | chassis.Run() 22 | } 23 | -------------------------------------------------------------------------------- /mutualtls/README.md: -------------------------------------------------------------------------------- 1 | this demo show how to enable mutual TLS communication between consumer and provider. 2 | 3 | 4 | check tls.yaml in each conf folder to learn -------------------------------------------------------------------------------- /mutualtls/client/client.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDXTCCAkWgAwIBAgIJAIO/zuOVNF+pMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV 3 | BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX 4 | aWRnaXRzIFB0eSBMdGQwHhcNMTkwMjI2MDQ0ODQyWhcNMjkwMjIzMDQ0ODQyWjBF 5 | MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50 6 | ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB 7 | CgKCAQEAy50d5/q63BIYr3m2h5gy33GpZ6AcoZyIMVoAfi2dGljEoTxp+toENBjF 8 | 8S9qBeAF2+j2hmsMeip4Jk2o0rGwh6/TtenwKGu80Ci8vJp3hpuTlnipyV7Z8hPx 9 | Tx4PXlT/DkfliMpsV3UK6rgJZ7ahcIZOM85P/Ufh4rs4ASXuEjFTSd6+pmoH9/GD 10 | oDR8OAYjjRc+0WR48N4gF1YagVI0P5EAlNIbtHPdt7oOLJ41irJATbaiNg3+SKvH 11 | gv+h8Bkia+MUcyw5g3+1nzsKu0pCoGlHo2BY/FgQXQrAu4trGPLy/A2+h7lTcL4s 12 | PEKX88YJuC6n9wWT/MrJ3luL5F69lwIDAQABo1AwTjAdBgNVHQ4EFgQUtWObOENp 13 | DQLMAAv914AcSenguyUwHwYDVR0jBBgwFoAUtWObOENpDQLMAAv914AcSenguyUw 14 | DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAj1Zc/9ZNhgRlmlL7Jt+E 15 | w0tXWMQPqu6MfsvffydICFXyQr/VjDe20ELS3JFtDNO3Vncv+TD6wnpBifYWlKmO 16 | SCOsCluQWooN29lxmWrfVZENCJZ4iimOyPNSeocOyH3NPmNNQ2+SkuyZMWVNo1fj 17 | x34a+6tiVw7IkxGCL5GnxepAurzKsCuaNJUA1GG8G04DN/XG9x4giEKGtnOsVQVf 18 | +6WTREM2bX4TItiOwayXUUmdMBj26s2jIAOp5v9sjRQEJQptL9kmcJFrGw+UFhm6 19 | MVFdDpcHF7xCPbde6u3i/Z7Ax0nosj1X4YTDZ2sUCQNg7e+W7G9wseK/VJHxabyF 20 | 1g== 21 | -----END CERTIFICATE----- 22 | -------------------------------------------------------------------------------- /mutualtls/client/client.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEpAIBAAKCAQEAy50d5/q63BIYr3m2h5gy33GpZ6AcoZyIMVoAfi2dGljEoTxp 3 | +toENBjF8S9qBeAF2+j2hmsMeip4Jk2o0rGwh6/TtenwKGu80Ci8vJp3hpuTlnip 4 | yV7Z8hPxTx4PXlT/DkfliMpsV3UK6rgJZ7ahcIZOM85P/Ufh4rs4ASXuEjFTSd6+ 5 | pmoH9/GDoDR8OAYjjRc+0WR48N4gF1YagVI0P5EAlNIbtHPdt7oOLJ41irJATbai 6 | Ng3+SKvHgv+h8Bkia+MUcyw5g3+1nzsKu0pCoGlHo2BY/FgQXQrAu4trGPLy/A2+ 7 | h7lTcL4sPEKX88YJuC6n9wWT/MrJ3luL5F69lwIDAQABAoIBAQDDnqvA2E72aBx3 8 | WkRXeY5GxnivKlDXo//lCkc28rPhQC+JiPV5IESxmKtz0M3X3ydB5EwVUHuoU20j 9 | v7DW3AhyFCceuycUbo30n27U9MKo/IeLJVpaMVrLDQXlsUeqpZZ2LfUEuxXj4Hsg 10 | jrfagMgRx7cSZsDK4mjO4HgqAjr8Fdakyry9nmJ4xVJHpvE/rvoADR3M2qEcrHRd 11 | HR899DURuVW1xT5gsXp7gE9ojPJLmBYGW5V48gwnFR6xKALa3cZohGuRfSxZww4y 12 | a9oS9oiFrLye/FbleKLEkNQGaJcI8RupzLFTxFrpMjaiG67qNS/kKbg4fh7GXxgZ 13 | zgmpYIGhAoGBAPzkLhx0gtiBuv+rHo0Qm2HVYYjxeZ6C7GVEVy71M6Q8peBYv39K 14 | sZac0X5d4+NtXbeeW6YTMPjWnxmGJE7zINi2iqOWRhyrxiLwXrRZeibAM9ydeW2Q 15 | cLe3pYtTMUzdp+0Wyh6HHKnOhBpA1Ift7J3wIhG9PeLBybevvCW+7fZ7AoGBAM4d 16 | 3aTgfiP/5ghNx9FuKUpM6Z2BGdBEjEJSxSr2KHiJIR9LhuzcDsRo2M6c3PuCsH7/ 17 | l4BOOSHFgeXkPUtEhpHsmLaCu3qrdW4Z2S4q+IJI4+GI2ZN6iuN/NfpLNKyYDuEH 18 | /BpM3RINxW5KhmePb6LgOeDhn6e26Agk30yuLFiVAoGAHu6J9VEK8BBuHvd/NSHi 19 | 34SJ+YYPqiO5ZmmFgGjdeCky4M36Hke0kQd9WEeDqD2oSN1FuHqAcu9NZoHRzxZN 20 | 3jP1oSywRrF7+qoL62NGXZcEwOdCAvS31MDRrsjuLsit0YIIFtPP3bU000E6vaWM 21 | W4UTpbfP6fxp/92u1a8UzCECgYB2JyinGwk0Gb0DhZLFuyBwNyaz4w2pFaJRYqEj 22 | v3fzoKgcCG+P15WfgXrG9aS3iHMkWd++7RhTA6Uy42M/gkih3b6s4MQXzbHDK44T 23 | qQ5LoP0AjDItGFIFlyaaFAJd7cyZsroRWX5gmwRR9OaW9uJHu8Fx5+Rdf7wC7yAS 24 | FMXXAQKBgQCm0AX1677LpHfRBx9aSWz/IlONRJ4iVsnpGXcsoHk7m5sGPxCLT9vI 25 | 7jFMxk7cAG0CrzxkfcnsvHVjx7inH+QU0ngQv9r+tQWPspWIz8F/prQzEr+K0wwv 26 | cG/f2gonwx9ZWd+bs9WItL9sq7eUW0mYEYEewHNW1ABE7KM91ui+yQ== 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /mutualtls/client/conf/chassis.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | cse: 3 | service: 4 | registry: 5 | address: http://127.0.0.1:30100 # If type is File then address will be the path of the file 6 | protocols: 7 | rest: 8 | listenAddress: "127.0.0.1:5001" 9 | #advertiseAddress: "internal_ip:5001" 10 | handler: 11 | chain: 12 | Provider: 13 | default: tracing-provider,bizkeeper-provider -------------------------------------------------------------------------------- /mutualtls/client/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | #微服务的私有属性 3 | service_description: 4 | name: RESTServer -------------------------------------------------------------------------------- /mutualtls/client/conf/tls.yaml: -------------------------------------------------------------------------------- 1 | ssl: 2 | TLSService.rest.Consumer.cipherSuits: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 3 | TLSService.rest.Consumer.protocol: TLSv1.2 4 | TLSService.rest.Consumer.caFile: server.crt 5 | TLSService.rest.Consumer.certFile: client.crt 6 | TLSService.rest.Consumer.keyFile: client.key 7 | TLSService.rest.Provider.verifyPeer: true -------------------------------------------------------------------------------- /mutualtls/client/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "github.com/go-chassis/go-chassis/v2" 6 | "github.com/go-chassis/go-chassis/v2/client/rest" 7 | "github.com/go-chassis/go-chassis/v2/core" 8 | "github.com/go-chassis/go-chassis/v2/core/common" 9 | "github.com/go-chassis/go-chassis/v2/pkg/util/httputil" 10 | "github.com/go-chassis/openlog" 11 | ) 12 | 13 | //if you use go run main.go instead of binary run, plz export CHASSIS_HOME=/{path}/{to}/client/ 14 | func main() { 15 | //Init framework 16 | if err := chassis.Init(); err != nil { 17 | openlog.Error("Init failed." + err.Error()) 18 | return 19 | } 20 | 21 | req, err := rest.NewRequest("GET", "http://TLSService/sayhello/world", nil) 22 | if err != nil { 23 | openlog.Error("new request failed.") 24 | return 25 | } 26 | 27 | ctx := context.WithValue(context.TODO(), common.ContextHeaderKey{}, map[string]string{ 28 | "user": "peter", 29 | }) 30 | resp, err := core.NewRestInvoker().ContextDo(ctx, req) 31 | if err != nil { 32 | openlog.Error("do request failed.") 33 | return 34 | } 35 | defer resp.Body.Close() 36 | openlog.Info("REST Server sayhello[GET]: " + string(httputil.ReadBody(resp))) 37 | } 38 | -------------------------------------------------------------------------------- /mutualtls/client/server.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICWDCCAcGgAwIBAgIJALU3kJeFqTthMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV 3 | BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX 4 | aWRnaXRzIFB0eSBMdGQwHhcNMTkwMjI2MDQ0MTEzWhcNMjkwMjIzMDQ0MTEzWjBF 5 | MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50 6 | ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB 7 | gQDA9TLWYKqmTI/jLqP1LP82n0OD/lC8TQqzS/GNRdZUEBKk/N9yoU9x7APUPFud 8 | hcJuTevgAklqNIHiJUQNB3/C5UkcKE4JbdqI71PtXvWH249rb9wjoQahhtGgjdmK 9 | 3A7N614X5ff04H3sRmAC12Q6itNO2ca9WDFbrDUotLS25QIDAQABo1AwTjAdBgNV 10 | HQ4EFgQU7880r5Q1fHhvEW27PqzhLQjSDhowHwYDVR0jBBgwFoAU7880r5Q1fHhv 11 | EW27PqzhLQjSDhowDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOBgQA7Busc 12 | Vw5Hnqs1lqjah8sXUH+So+6GQXYTf5kEv9IxuY2zseRIQH3iO9LQIBiwIwBrUeNf 13 | tgpY28mfVk9V4a+ps2PAlrOypEh7sC/Dh3KC27efEcUffuSHGgV4SjhA1AdqjJCH 14 | vURc3cUJ5u2oDy/oGLK2si7OcJTRF9An/0qexQ== 15 | -----END CERTIFICATE----- 16 | -------------------------------------------------------------------------------- /mutualtls/server/client.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDXTCCAkWgAwIBAgIJAIO/zuOVNF+pMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV 3 | BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX 4 | aWRnaXRzIFB0eSBMdGQwHhcNMTkwMjI2MDQ0ODQyWhcNMjkwMjIzMDQ0ODQyWjBF 5 | MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50 6 | ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB 7 | CgKCAQEAy50d5/q63BIYr3m2h5gy33GpZ6AcoZyIMVoAfi2dGljEoTxp+toENBjF 8 | 8S9qBeAF2+j2hmsMeip4Jk2o0rGwh6/TtenwKGu80Ci8vJp3hpuTlnipyV7Z8hPx 9 | Tx4PXlT/DkfliMpsV3UK6rgJZ7ahcIZOM85P/Ufh4rs4ASXuEjFTSd6+pmoH9/GD 10 | oDR8OAYjjRc+0WR48N4gF1YagVI0P5EAlNIbtHPdt7oOLJ41irJATbaiNg3+SKvH 11 | gv+h8Bkia+MUcyw5g3+1nzsKu0pCoGlHo2BY/FgQXQrAu4trGPLy/A2+h7lTcL4s 12 | PEKX88YJuC6n9wWT/MrJ3luL5F69lwIDAQABo1AwTjAdBgNVHQ4EFgQUtWObOENp 13 | DQLMAAv914AcSenguyUwHwYDVR0jBBgwFoAUtWObOENpDQLMAAv914AcSenguyUw 14 | DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAj1Zc/9ZNhgRlmlL7Jt+E 15 | w0tXWMQPqu6MfsvffydICFXyQr/VjDe20ELS3JFtDNO3Vncv+TD6wnpBifYWlKmO 16 | SCOsCluQWooN29lxmWrfVZENCJZ4iimOyPNSeocOyH3NPmNNQ2+SkuyZMWVNo1fj 17 | x34a+6tiVw7IkxGCL5GnxepAurzKsCuaNJUA1GG8G04DN/XG9x4giEKGtnOsVQVf 18 | +6WTREM2bX4TItiOwayXUUmdMBj26s2jIAOp5v9sjRQEJQptL9kmcJFrGw+UFhm6 19 | MVFdDpcHF7xCPbde6u3i/Z7Ax0nosj1X4YTDZ2sUCQNg7e+W7G9wseK/VJHxabyF 20 | 1g== 21 | -----END CERTIFICATE----- 22 | -------------------------------------------------------------------------------- /mutualtls/server/conf/TLSService/schema/TLSService.yaml: -------------------------------------------------------------------------------- 1 | swagger: "2.0" 2 | info: 3 | title: "" 4 | version: "" 5 | basePath: / 6 | paths: 7 | /: 8 | get: 9 | operationId: func1 10 | consumes: 11 | - application/xml 12 | - application/json 13 | - application/octet-stream 14 | - multipart/form-data 15 | produces: 16 | - application/json 17 | - application/xml 18 | - application/octet-stream 19 | - multipart/form-data 20 | responses: 21 | "200": 22 | description: "" 23 | /sayhello/{userid}: 24 | get: 25 | operationId: func2 26 | consumes: 27 | - application/xml 28 | - application/json 29 | - application/octet-stream 30 | - multipart/form-data 31 | produces: 32 | - application/json 33 | - application/xml 34 | - application/octet-stream 35 | - multipart/form-data 36 | responses: 37 | "200": 38 | description: "" 39 | /sayhi: 40 | post: 41 | operationId: func3 42 | consumes: 43 | - application/xml 44 | - application/json 45 | - application/octet-stream 46 | - multipart/form-data 47 | produces: 48 | - application/json 49 | - application/xml 50 | - application/octet-stream 51 | - multipart/form-data 52 | responses: 53 | "200": 54 | description: "" 55 | /sayjson: 56 | post: 57 | operationId: func4 58 | consumes: 59 | - application/xml 60 | - application/json 61 | - application/octet-stream 62 | - multipart/form-data 63 | produces: 64 | - application/json 65 | - application/xml 66 | - application/octet-stream 67 | - multipart/form-data 68 | responses: 69 | "200": 70 | description: "" 71 | -------------------------------------------------------------------------------- /mutualtls/server/conf/chassis.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | cse: 3 | service: 4 | registry: 5 | address: http://127.0.0.1:30100 # If type is File then address will be the path of the file 6 | protocols: 7 | rest: 8 | listenAddress: 127.0.0.1:3000 9 | #advertiseAddress: "internal_ip:5001" 10 | handler: 11 | chain: 12 | Provider: 13 | default: tracing-provider,bizkeeper-provider -------------------------------------------------------------------------------- /mutualtls/server/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | #微服务的私有属性 3 | service_description: 4 | name: TLSService -------------------------------------------------------------------------------- /mutualtls/server/conf/tls.yaml: -------------------------------------------------------------------------------- 1 | ssl: 2 | rest.Provider.cipherPlugin: default 3 | rest.Provider.cipherSuits: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 4 | rest.Provider.protocol: TLSv1.2 5 | rest.Provider.keyFile: server.key 6 | rest.Provider.certFile: server.crt 7 | rest.Provider.caFile: client.crt 8 | rest.Provider.verifyPeer: true 9 | rest.Provider.certPwdFile: pwd -------------------------------------------------------------------------------- /mutualtls/server/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/go-chassis/go-chassis/v2" 5 | "github.com/go-chassis/go-chassis/v2/core/server" 6 | "github.com/go-chassis/go-chassis/v2/examples/schemas" 7 | "github.com/go-chassis/openlog" 8 | ) 9 | 10 | //if you use go run main.go instead of binary run, plz export CHASSIS_HOME=/{path}/{to}/rest/server/ 11 | 12 | func main() { 13 | chassis.RegisterSchema("rest", &schemas.RestFulHello{}, server.WithSchemaID("RestHelloService")) 14 | if err := chassis.Init(); err != nil { 15 | openlog.Error("Init failed." + err.Error()) 16 | return 17 | } 18 | chassis.Run() 19 | } 20 | -------------------------------------------------------------------------------- /mutualtls/server/pwd: -------------------------------------------------------------------------------- 1 | change -------------------------------------------------------------------------------- /mutualtls/server/server.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICWDCCAcGgAwIBAgIJALU3kJeFqTthMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV 3 | BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX 4 | aWRnaXRzIFB0eSBMdGQwHhcNMTkwMjI2MDQ0MTEzWhcNMjkwMjIzMDQ0MTEzWjBF 5 | MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50 6 | ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB 7 | gQDA9TLWYKqmTI/jLqP1LP82n0OD/lC8TQqzS/GNRdZUEBKk/N9yoU9x7APUPFud 8 | hcJuTevgAklqNIHiJUQNB3/C5UkcKE4JbdqI71PtXvWH249rb9wjoQahhtGgjdmK 9 | 3A7N614X5ff04H3sRmAC12Q6itNO2ca9WDFbrDUotLS25QIDAQABo1AwTjAdBgNV 10 | HQ4EFgQU7880r5Q1fHhvEW27PqzhLQjSDhowHwYDVR0jBBgwFoAU7880r5Q1fHhv 11 | EW27PqzhLQjSDhowDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOBgQA7Busc 12 | Vw5Hnqs1lqjah8sXUH+So+6GQXYTf5kEv9IxuY2zseRIQH3iO9LQIBiwIwBrUeNf 13 | tgpY28mfVk9V4a+ps2PAlrOypEh7sC/Dh3KC27efEcUffuSHGgV4SjhA1AdqjJCH 14 | vURc3cUJ5u2oDy/oGLK2si7OcJTRF9An/0qexQ== 15 | -----END CERTIFICATE----- 16 | -------------------------------------------------------------------------------- /mutualtls/server/server.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | Proc-Type: 4,ENCRYPTED 3 | DEK-Info: DES-EDE3-CBC,88494FBC7A9FD2BB 4 | 5 | dAb6aAZJTEN59o75NAxchvDUoUlObheD1+OufpXaoO6I95PZeVPhT5SGIgagKimW 6 | 8GOKGpV6JDRu0ilAtWMfoJH7F/xNnfKDliL/mz6FDfUKdwoWW+FUZf0NnETR3bZI 7 | 29GfG0Kgj3ni8OpkWvHsQK7EhywBMEvXz1Z1SWGeaHPv32cQU9fjuvIpEFuezyFs 8 | nXivtVjH6QcVpzQmgCS4FcEyssNPbs82w79h23/FKSe7bk91uT6ZJ6h+EPwXG53f 9 | 1RauxiQcwX6t/9um5VcyeFYsmv+gJSaySh43Q8gn9w/ZbWURzCgtMDu2T62zPF7b 10 | kKCpmzDBFSeKzbL7OG+0329XOgc68Bk349pWWMa2iiBtCeIDj+tR3V/dKQYrodzF 11 | 5Ols7rlTYEGLybkD24+2z66PofWS08FHu59xtGR1mp2TwbLdobnNFI1H1Q+1mX6H 12 | Ek25RTXGwoZGM1b50W0TZJmf7ZdM5vzOB7Qi1r+m7gbhKGcL+xJ4hhWFBuDTQ1Gl 13 | pLWhMHswKoK0OBx4Ijufm8Qufb8ViF+Q8Nr3JMYhEva3na76TA/7OiJLvffKtt3n 14 | jgZZx6K8jxZu0ypoh2mpVLEqQIDguvkMc6sEfX3RMUV2HXt2Z/j9UH9rN9P/4uc3 15 | 94lFwmyWUS+ACJDVekxgSTB/fBQtlxEEXbgoCPFyPdp7ZgqfnU+3KEE25ulq9NiV 16 | JDzfRoa3UpKJ6Lcg2p1r9UNsRnW2Xo7On5K/eWRpL3EU+eJ9HS+5Ep8V/qOzySD6 17 | kD9TdJ2xrBeieeOfP7KXh7YwOpbMBuqnyxVlMKQzDqgyPiV2lfBhlA== 18 | -----END RSA PRIVATE KEY----- 19 | -------------------------------------------------------------------------------- /protocol/README.md: -------------------------------------------------------------------------------- 1 | # Protocol examples 2 | 3 | 4 | # Benchmarks 5 | | Plugin | Thoughput | Latency | CPU | Mem | 6 | |------------ |----------- |--------- |------ |------ | 7 | | fiber | 54638tps | 0.88ms | 170% | 20mb | 8 | | go-restful | 23564tps | 1.4ms | 200% | 22mb | 9 | ## Conclusion 10 | fiber is 2.43x faster than go-restful with less cpu and mem consumption -------------------------------------------------------------------------------- /protocol/gofiber/server/conf/chassis.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | servicecomb: 3 | registry: 4 | address: http://127.0.0.1:30100 5 | disabled: true 6 | protocols: 7 | rest: 8 | listenAddress: 127.0.0.1:9000 -------------------------------------------------------------------------------- /protocol/gofiber/server/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | servicecomb: 2 | service: 3 | name: HelloFiber -------------------------------------------------------------------------------- /protocol/gofiber/server/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/go-chassis/go-chassis/v2" 5 | 6 | _ "github.com/go-chassis/go-chassis-extension/protocol/fiber4r" 7 | 8 | "github.com/go-chassis/openlog" 9 | "github.com/gofiber/fiber/v2" 10 | ) 11 | 12 | func SayHello(c *fiber.Ctx) error { 13 | return c.SendString("hello. go chassis") 14 | } 15 | 16 | func main() { 17 | app := fiber.New() 18 | app.Get("/", SayHello) 19 | chassis.RegisterSchema("rest", app) 20 | if err := chassis.Init(); err != nil { 21 | openlog.Fatal("init failed." + err.Error()) 22 | return 23 | } 24 | if err := chassis.Run(); err != nil { 25 | openlog.Fatal("run failed." + err.Error()) 26 | return 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /protocol/gorestful/conf/chassis.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | servicecomb: 3 | registry: 4 | address: http://127.0.0.1:30100 5 | disabled: true 6 | protocols: 7 | rest: 8 | listenAddress: 127.0.0.1:7000 -------------------------------------------------------------------------------- /protocol/gorestful/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | servicecomb: 2 | service: 3 | name: HelloResftul -------------------------------------------------------------------------------- /protocol/gorestful/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/go-chassis/go-chassis/v2" 5 | rf "github.com/go-chassis/go-chassis/v2/server/restful" 6 | "github.com/go-chassis/openlog" 7 | "net/http" 8 | ) 9 | 10 | type HelloResource struct { 11 | } 12 | 13 | func (r *HelloResource) SayHi(b *rf.Context) { 14 | b.Write([]byte("hello. go chassis")) 15 | return 16 | } 17 | 18 | func (r *HelloResource) URLPatterns() []rf.Route { 19 | return []rf.Route{ 20 | {Method: http.MethodGet, Path: "/hello", ResourceFunc: r.SayHi}, 21 | } 22 | } 23 | 24 | //if you use go run main.go instead of binary run, plz export CHASSIS_HOME=/{path}/{to}/server/ 25 | 26 | func main() { 27 | chassis.RegisterSchema("rest", &HelloResource{}) 28 | if err := chassis.Init(); err != nil { 29 | openlog.Fatal("Init failed." + err.Error()) 30 | return 31 | } 32 | chassis.Run() 33 | } 34 | -------------------------------------------------------------------------------- /router/servicecomb/README.md: -------------------------------------------------------------------------------- 1 | # Router example 2 | 3 | In this example we will run two different versions service and one client.We will show you how to 4 | implement grayscale publishing of the application with route management,version V1 is simulation 5 | you old service , version V2 is simulation you new service. 6 | 1. Build and Run Service V1 and Service V2 7 | 8 | 9 | we use microservice.yaml to set service config,and we must set two service with the 10 | same service name,set different version for two service 11 | 12 | 13 | Service V1 14 | ```yaml 15 | #Private property of microservices 16 | service_description: 17 | name: ROUTERServer 18 | version: 1.0 19 | ``` 20 | 21 | Service V2 22 | ```yaml 23 | #Private property of microservices 24 | service_description: 25 | name: ROUTERServer 26 | version: 2.0 27 | ``` 28 | 29 | build and run two service 30 | 31 | ```bash 32 | cd serverV1 33 | go build main.go 34 | ./main 35 | ``` 36 | ```bash 37 | cd serverV2 38 | go build main.go 39 | ./main 40 | ``` 41 | 42 | 2. Build and run client 43 | 44 | client use router.yaml to management router.Configuration of this file 45 | use router.yaml launch client 46 | ```yaml 47 | servicecomb: 48 | routeRule: 49 | paymentService: | 50 | - precedence: 1 # 优先级,数字越大优先级越高 51 | route: #路由规则列表 52 | - tags: 53 | version: 1.0 54 | project: x 55 | weight: 50 #全重 50%到这里 56 | - tags: 57 | version: 2.0 58 | project: z 59 | weight: 50 #全重 50%到这里 60 | ``` 61 | 62 | build and run client 63 | ```bash 64 | cd client 65 | go build main.go 66 | ./main 67 | ``` 68 | 69 | 70 | result: 71 | 72 | {"level":"INFO","timestamp":"2019-10-16 12:57:29.893 +08:00","file":"client/main.go:43","msg":"paymentService response: version V1 was called: 1 times"} 73 | {"level":"INFO","timestamp":"2019-10-16 12:57:30.896 +08:00","file":"client/main.go:43","msg":"paymentService response: version V2 was called: 1 times"} 74 | {"level":"INFO","timestamp":"2019-10-16 12:57:31.899 +08:00","file":"client/main.go:43","msg":"paymentService response: version V1 was called: 2 times"} 75 | {"level":"INFO","timestamp":"2019-10-16 12:57:32.901 +08:00","file":"client/main.go:43","msg":"paymentService response: version V2 was called: 2 times"} 76 | {"level":"INFO","timestamp":"2019-10-16 12:57:33.903 +08:00","file":"client/main.go:43","msg":"paymentService response: version V1 was called: 3 times"} 77 | {"level":"INFO","timestamp":"2019-10-16 12:57:34.905 +08:00","file":"client/main.go:43","msg":"paymentService response: version V2 was called: 3 times"} 78 | {"level":"INFO","timestamp":"2019-10-16 12:57:35.906 +08:00","file":"client/main.go:43","msg":"paymentService response: version V1 was called: 4 times"} 79 | {"level":"INFO","timestamp":"2019-10-16 12:57:36.908 +08:00","file":"client/main.go:43","msg":"paymentService response: version V2 was called: 4 times"} 80 | {"level":"INFO","timestamp":"2019-10-16 12:57:37.910 +08:00","file":"client/main.go:43","msg":"paymentService response: version V1 was called: 5 times"} 81 | {"level":"INFO","timestamp":"2019-10-16 12:57:38.910 +08:00","file":"client/main.go:43","msg":"paymentService response: version V2 was called: 5 times"} 82 | -------------------------------------------------------------------------------- /router/servicecomb/client/conf/chassis.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | #APPLICATION_ID: CSE optional 3 | cse: 4 | service: 5 | registry: 6 | address: http://127.0.0.1:30100 7 | config: 8 | client: 9 | serverUri: http://127.0.0.1:30110 10 | type: servicecomb-kie 11 | protocols: 12 | rest: 13 | listenAddress: 127.0.0.1:9000 -------------------------------------------------------------------------------- /router/servicecomb/client/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | service_description: 3 | name: orderService -------------------------------------------------------------------------------- /router/servicecomb/client/conf/router.yaml: -------------------------------------------------------------------------------- 1 | servicecomb: 2 | routeRule: 3 | paymentService: | 4 | - precedence: 1 # 优先级,数字越大优先级越高 5 | route: #路由规则列表 6 | - tags: 7 | version: 1.0 8 | project: x 9 | weight: 50 #全重 50%到这里 10 | - tags: 11 | version: 2.0 12 | project: z 13 | weight: 50 #全重 50%到这里 14 | 15 | -------------------------------------------------------------------------------- /router/servicecomb/client/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "github.com/go-chassis/openlog" 6 | "net/http" 7 | 8 | "github.com/go-chassis/go-chassis/v2" 9 | _ "github.com/go-chassis/go-chassis/v2/bootstrap" 10 | "github.com/go-chassis/go-chassis/v2/client/rest" 11 | "github.com/go-chassis/go-chassis/v2/core" 12 | "github.com/go-chassis/go-chassis/v2/pkg/util/httputil" 13 | "github.com/go-chassis/go-chassis/v2/server/restful" 14 | ) 15 | 16 | // RestFulRouterB is a struct used for implementation of restfull router program 17 | type RestFulRouterB struct { 18 | called int 19 | } 20 | 21 | // Equal is method to compare given num and slice product 22 | func (r *RestFulRouterB) GetPayments(ctx *restful.Context) { 23 | req, err := rest.NewRequest("GET", "http://paymentService/payments", nil) 24 | if err != nil { 25 | openlog.Error("new request failed.") 26 | return 27 | } 28 | 29 | resp, err := core.NewRestInvoker().ContextDo(context.Background(), req) 30 | if err != nil { 31 | openlog.Error("do request failed.") 32 | return 33 | } 34 | defer resp.Body.Close() 35 | 36 | ctx.Write(httputil.ReadBody(resp)) 37 | } 38 | 39 | // URLPatterns helps to respond for corresponding API calls 40 | func (r *RestFulRouterB) URLPatterns() []restful.Route { 41 | return []restful.Route{ 42 | {Method: http.MethodGet, Path: "/payments", ResourceFunc: r.GetPayments}, 43 | } 44 | } 45 | 46 | func main() { 47 | chassis.RegisterSchema("rest", &RestFulRouterB{}) 48 | //Init framework 49 | if err := chassis.Init(); err != nil { 50 | openlog.Error("Init failed." + err.Error()) 51 | return 52 | } 53 | chassis.Run() 54 | } 55 | -------------------------------------------------------------------------------- /router/servicecomb/resource/restful_router_V1.go: -------------------------------------------------------------------------------- 1 | package resource 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "strconv" 7 | 8 | "github.com/go-chassis/go-chassis/v2/server/restful" 9 | ) 10 | 11 | // RestFulRouterA is a struct used for implementation of restfull router program 12 | type RestFulRouterA struct { 13 | called int 14 | } 15 | 16 | func (r *RestFulRouterA) GetPayments(context *restful.Context) { 17 | r.called++ 18 | context.Write([]byte(fmt.Sprintf("version V1 was called: %d times", r.called))) 19 | } 20 | 21 | // Say is method to reply version A say some info 22 | func (r *RestFulRouterA) Say(context *restful.Context) { 23 | reslut := struct { 24 | Name string 25 | Addr string 26 | Age int 27 | }{} 28 | err := context.ReadEntity(&reslut) 29 | if err != nil { 30 | context.Write([]byte(err.Error())) 31 | return 32 | } 33 | context.Write([]byte("version V1 : " + reslut.Name + " say : he is " + 34 | strconv.Itoa(reslut.Age) + " years ago ,live in " + reslut.Addr)) 35 | } 36 | 37 | // Operation is method to add two num sum 38 | func (r *RestFulRouterA) Operation(context *restful.Context) { 39 | paramMap := context.ReadPathParameters() 40 | numString1 := paramMap["num1"] 41 | numString2 := paramMap["num2"] 42 | num1, err := strconv.Atoi(numString1) 43 | if err != nil { 44 | context.WriteHeaderAndJSON(http.StatusInternalServerError, err, "application/json") 45 | return 46 | } 47 | num2, err := strconv.Atoi(numString2) 48 | if err != nil { 49 | context.WriteHeaderAndJSON(http.StatusInternalServerError, err, "application/json") 50 | return 51 | } 52 | sum := num1 + num2 53 | context.Write([]byte(fmt.Sprintf("version V1 : calculate the sum of the two numbers ,the sum is %d .", sum))) 54 | } 55 | 56 | // Info is a method used to reply version information 57 | func (r *RestFulRouterA) Info(context *restful.Context) { 58 | versionInfo := struct { 59 | Name string `json:"name"` 60 | Version string `json:"version"` 61 | HostName string `json:"hostName"` 62 | }{ 63 | Name: "CHASSIS_SERVER_V1", 64 | Version: "1.0", 65 | HostName: context.ReadRequest().Host, 66 | } 67 | 68 | context.WriteJSON(versionInfo, "application/json") 69 | } 70 | 71 | // URLPatterns helps to respond for corresponding API calls 72 | func (r *RestFulRouterA) URLPatterns() []restful.Route { 73 | return []restful.Route{ 74 | {Method: http.MethodGet, Path: "/info", ResourceFunc: r.Info}, 75 | {Method: http.MethodGet, Path: "/operation/{num1}/{num2}", ResourceFunc: r.Operation}, 76 | {Method: http.MethodPost, Path: "/say", ResourceFunc: r.Say}, 77 | {Method: http.MethodGet, Path: "/payments", ResourceFunc: r.GetPayments}, 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /router/servicecomb/resource/restful_router_V2.go: -------------------------------------------------------------------------------- 1 | package resource 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "strconv" 7 | "time" 8 | 9 | "github.com/go-chassis/go-chassis/v2/server/restful" 10 | ) 11 | 12 | // RestFulRouterB is a struct used for implementation of restfull router program 13 | type RestFulRouterB struct { 14 | called int 15 | } 16 | 17 | // Equal is method to compare given num and slice product 18 | func (r *RestFulRouterB) GetPayments(context *restful.Context) { 19 | r.called++ 20 | context.Write([]byte(fmt.Sprintf("version V2 was called: %d times", r.called))) 21 | } 22 | 23 | // Say is method to reply version B say some info 24 | func (r *RestFulRouterB) Say(context *restful.Context) { 25 | reslut := struct { 26 | Name string 27 | Addr string 28 | Age int 29 | Phone string 30 | }{} 31 | err := context.ReadEntity(&reslut) 32 | if err != nil { 33 | context.Write([]byte(err.Error())) 34 | return 35 | } 36 | if reslut.Phone == "" { 37 | reslut.Phone = "13800138000" 38 | } 39 | context.Write([]byte("version V2 : " + reslut.Name + " say : he is " + strconv.Itoa(reslut.Age) + 40 | " years ago , live in " + reslut.Addr + " ,phone is " + reslut.Phone)) 41 | } 42 | 43 | // Operation is method to calculate two num product 44 | func (r *RestFulRouterB) Operation(context *restful.Context) { 45 | paramMap := context.ReadPathParameters() 46 | numString1 := paramMap["num1"] 47 | numString2 := paramMap["num2"] 48 | num1, err := strconv.Atoi(numString1) 49 | if err != nil { 50 | context.WriteHeaderAndJSON(http.StatusInternalServerError, err, "application/json") 51 | return 52 | } 53 | num2, err := strconv.Atoi(numString2) 54 | if err != nil { 55 | context.WriteHeaderAndJSON(http.StatusInternalServerError, err, "application/json") 56 | return 57 | } 58 | product := num1 * num2 59 | context.Write([]byte(fmt.Sprintf("version V2 : calculate the product of the two numbers ,the product is %d .", product))) 60 | } 61 | 62 | // Info is a method used to reply version information 63 | func (r *RestFulRouterB) Info(context *restful.Context) { 64 | versionInfo := struct { 65 | Name string `json:"name"` 66 | Version string `json:"version"` 67 | HostName string `json:"hostName"` 68 | Now int64 `json:"now"` 69 | }{ 70 | Name: "CHASSIS_SERVER_V2", 71 | Version: "2.0", 72 | HostName: context.ReadRequest().Host, 73 | Now: time.Now().UnixNano() / 1e6, 74 | } 75 | context.WriteJSON(versionInfo, "application/json") 76 | } 77 | 78 | // URLPatterns helps to respond for corresponding API calls 79 | func (r *RestFulRouterB) URLPatterns() []restful.Route { 80 | return []restful.Route{ 81 | {Method: http.MethodGet, Path: "/info", ResourceFunc: r.Info}, 82 | {Method: http.MethodGet, Path: "/operation/{num1}/{num2}", ResourceFunc: r.Operation}, 83 | {Method: http.MethodPost, Path: "/say", ResourceFunc: r.Say}, 84 | {Method: http.MethodGet, Path: "/payments", ResourceFunc: r.GetPayments}, 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /router/servicecomb/serverV1/conf/chassis.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | cse: 3 | service: 4 | registry: 5 | address: http://127.0.0.1:30100 # If type is File then address will be the path of the file 6 | protocols: 7 | rest: 8 | listenAddress: 127.0.0.1:5002 9 | advertiseAddress: 127.0.0.1:5002 10 | handler: 11 | chain: 12 | Provider: 13 | default: tracing-provider,bizkeeper-provider -------------------------------------------------------------------------------- /router/servicecomb/serverV1/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | #Private property of microservices 3 | service_description: 4 | name: paymentService 5 | version: 1.0 6 | instance_properties: 7 | project: x -------------------------------------------------------------------------------- /router/servicecomb/serverV1/conf/paymentService/schema/paymentService.yaml: -------------------------------------------------------------------------------- 1 | swagger: "2.0" 2 | info: 3 | title: "" 4 | version: "" 5 | basePath: / 6 | paths: 7 | /info: 8 | get: 9 | operationId: Info 10 | consumes: 11 | - '*/*' 12 | produces: 13 | - '*/*' 14 | /operation/{num1}/{num2}: 15 | get: 16 | operationId: Operation 17 | consumes: 18 | - '*/*' 19 | produces: 20 | - '*/*' 21 | /payments: 22 | get: 23 | operationId: GetPayments 24 | consumes: 25 | - '*/*' 26 | produces: 27 | - '*/*' 28 | /say: 29 | post: 30 | operationId: Say 31 | consumes: 32 | - '*/*' 33 | produces: 34 | - '*/*' 35 | -------------------------------------------------------------------------------- /router/servicecomb/serverV1/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/go-chassis/go-chassis-examples/router/servicecomb/resource" 5 | "github.com/go-chassis/go-chassis/v2" 6 | "github.com/go-chassis/go-chassis/v2/core/server" 7 | "github.com/go-chassis/openlog" 8 | ) 9 | 10 | //if you use go run main.go instead of binary run, plz export CHASSIS_HOME=/{path}/{to}/rpc/server/ 11 | 12 | func main() { 13 | chassis.RegisterSchema("rest", &resource.RestFulRouterA{}, server.WithSchemaID("RestROUTERService")) 14 | if err := chassis.Init(); err != nil { 15 | openlog.Error("Init failed." + err.Error()) 16 | return 17 | } 18 | chassis.Run() 19 | } 20 | -------------------------------------------------------------------------------- /router/servicecomb/serverV2/conf/chassis.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | cse: 3 | service: 4 | registry: 5 | address: http://127.0.0.1:30100 # If type is File then address will be the path of the file 6 | protocols: 7 | rest: 8 | listenAddress: 127.0.0.1:5001 9 | advertiseAddress: 127.0.0.1:5001 10 | handler: 11 | chain: 12 | Provider: 13 | default: tracing-provider,bizkeeper-provider -------------------------------------------------------------------------------- /router/servicecomb/serverV2/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | #微服务的私有属性 3 | service_description: 4 | name: paymentService 5 | version: 2.0 6 | instance_properties: 7 | project: z -------------------------------------------------------------------------------- /router/servicecomb/serverV2/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/go-chassis/go-chassis-examples/router/servicecomb/resource" 5 | "github.com/go-chassis/go-chassis/v2" 6 | "github.com/go-chassis/go-chassis/v2/core/server" 7 | "github.com/go-chassis/openlog" 8 | ) 9 | 10 | //if you use go run main.go instead of binary run, plz export CHASSIS_HOME=/{path}/{to}/rpc/server/ 11 | 12 | func main() { 13 | chassis.RegisterSchema("rest", &resource.RestFulRouterB{}, server.WithSchemaID("RestROUTERService")) 14 | if err := chassis.Init(); err != nil { 15 | openlog.Error("Init failed." + err.Error()) 16 | return 17 | } 18 | chassis.Run() 19 | } 20 | -------------------------------------------------------------------------------- /router_url/server/README.md: -------------------------------------------------------------------------------- 1 | ## Regular Expression 2 | 3 | go-chassis rest protocol support path parameter and dynamic url 4 | 5 | 6 | 1 path parameter 7 | 8 | set path parameter for rest protocol ,like 9 | ```go 10 | []restful.Route{ 11 | {Method: "GET", Path: "/param/{path_parameter}", ResourceFuncName: "Func_Name"}, 12 | } 13 | ``` 14 | The above example shows that `path_parameter` is the name of path parameter.you can get value through it. 15 | 16 | 17 | 2 dynamic router 18 | 19 | use regex to implement dynamic router , you can match all access like 20 | ```go 21 | []restful.Route{ 22 | {Method: "GET", Path: "/dynamic/{dynamic:*}", ResourceFuncName: "Func_Name"}, 23 | } 24 | ``` 25 | 26 | The above example shows can match all call which url prefix is `/dynamic` . 27 | If you did not match all call , you can only match letter with regex, like 28 | ```go 29 | []restful.Route{ 30 | {Method: "GET", Path: "/dynamic/{dynamic:[a-zA-Z]}", ResourceFuncName: "Func_Name"}, 31 | } 32 | ``` -------------------------------------------------------------------------------- /router_url/server/conf/chassis.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | cse: 3 | service: 4 | registry: 5 | type: servicecenter 6 | # address: https://cse.cn-north-1.myhuaweicloud.com 7 | address: http://127.0.0.1:30100 8 | protocols: 9 | rest: 10 | listenAddress: 127.0.0.1:8081 11 | advertiseAddress: 127.0.0.1:8081 -------------------------------------------------------------------------------- /router_url/server/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | #微服务的私有属性 3 | service_description: 4 | name: RESTServer 5 | -------------------------------------------------------------------------------- /router_url/server/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/go-chassis/go-chassis-examples/router_url/server/schema" 5 | "github.com/go-chassis/go-chassis/v2" 6 | "github.com/go-chassis/go-chassis/v2/core/server" 7 | ) 8 | 9 | func main() { 10 | chassis.RegisterSchema("rest", &schema.Server{}, server.WithSchemaID("test")) 11 | if err := chassis.Init(); err != nil { 12 | panic(err) 13 | } 14 | chassis.Run() 15 | } 16 | -------------------------------------------------------------------------------- /router_url/server/schema/schema.go: -------------------------------------------------------------------------------- 1 | package schema 2 | 3 | import ( 4 | "net/http" 5 | 6 | "github.com/go-chassis/go-chassis/v2/server/restful" 7 | ) 8 | 9 | type Server struct{} 10 | 11 | func (*Server) PathParm(ctx *restful.Context) { 12 | name := ctx.ReadPathParameter("name") 13 | ctx.Write([]byte("name for path param is : " + name)) 14 | } 15 | 16 | func (*Server) DynamicURL(ctx *restful.Context) { 17 | ctx.Write([]byte("dynamic path : " + ctx.ReadPathParameter("dynamic"))) 18 | } 19 | 20 | func (*Server) DynamicURLLetter(ctx *restful.Context) { 21 | ctx.Write([]byte("dynamic path : " + ctx.ReadPathParameter("dynamic"))) 22 | } 23 | 24 | func (*Server) AllAccess(ctx *restful.Context) { 25 | ctx.Write([]byte("dynamic path : " + ctx.ReadPathParameter("dynamic"))) 26 | } 27 | func (*Server) URLPatterns() []restful.Route { 28 | return []restful.Route{ 29 | {Method: http.MethodGet, Path: "/param/{name}", ResourceFuncName: "PathParm"}, 30 | {Method: http.MethodGet, Path: "/dynamic/{dynamic:*}", ResourceFuncName: "DynamicURL"}, 31 | {Method: http.MethodGet, Path: "/dynamic_letter/{dynamic:[a-zA-Z]}", ResourceFuncName: "DynamicURLLetter"}, 32 | {Method: http.MethodGet, Path: "/{dynamic:*}", ResourceFuncName: "AllAccess"}, 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /tls/README.md: -------------------------------------------------------------------------------- 1 | this demo show how to enable https communication between consumer and provider, 2 | it is not mutual TLS. 3 | 4 | 5 | check tls.yaml in each conf folder to learn -------------------------------------------------------------------------------- /tls/client/conf/chassis.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | cse: 3 | service: 4 | registry: 5 | address: http://127.0.0.1:30100 # If type is File then address will be the path of the file 6 | protocols: 7 | rest: 8 | listenAddress: "127.0.0.1:5001" 9 | #advertiseAddress: "internal_ip:5001" 10 | handler: 11 | chain: 12 | Provider: 13 | default: tracing-provider,bizkeeper-provider -------------------------------------------------------------------------------- /tls/client/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | #微服务的私有属性 3 | service_description: 4 | name: RESTServer -------------------------------------------------------------------------------- /tls/client/conf/tls.yaml: -------------------------------------------------------------------------------- 1 | ssl: 2 | TLSService.rest.Consumer.cipherSuits: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 3 | TLSService.rest.Consumer.protocol: TLSv1.2 -------------------------------------------------------------------------------- /tls/client/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "github.com/go-chassis/go-chassis/v2" 6 | "github.com/go-chassis/go-chassis/v2/client/rest" 7 | "github.com/go-chassis/go-chassis/v2/core" 8 | "github.com/go-chassis/go-chassis/v2/core/common" 9 | "github.com/go-chassis/go-chassis/v2/pkg/util/httputil" 10 | "github.com/go-chassis/openlog" 11 | ) 12 | 13 | //if you use go run main.go instead of binary run, plz export CHASSIS_HOME=/{path}/{to}/client/ 14 | func main() { 15 | //Init framework 16 | if err := chassis.Init(); err != nil { 17 | openlog.Error("Init failed." + err.Error()) 18 | return 19 | } 20 | 21 | req, err := rest.NewRequest("GET", "http://TLSService/sayhello/world", nil) 22 | if err != nil { 23 | openlog.Error("new request failed.") 24 | return 25 | } 26 | 27 | ctx := context.WithValue(context.TODO(), common.ContextHeaderKey{}, map[string]string{ 28 | "user": "peter", 29 | }) 30 | resp, err := core.NewRestInvoker().ContextDo(ctx, req) 31 | if err != nil { 32 | openlog.Error("do request failed.") 33 | return 34 | } 35 | defer resp.Body.Close() 36 | openlog.Info("REST Server sayhello[GET]: " + string(httputil.ReadBody(resp))) 37 | } 38 | -------------------------------------------------------------------------------- /tls/server/conf/chassis.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | cse: 3 | service: 4 | registry: 5 | address: http://127.0.0.1:30100 # If type is File then address will be the path of the file 6 | protocols: 7 | rest: 8 | listenAddress: 127.0.0.1:3000 9 | #advertiseAddress: "internal_ip:3000" 10 | handler: 11 | chain: 12 | Provider: 13 | default: tracing-provider,bizkeeper-provider -------------------------------------------------------------------------------- /tls/server/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | #微服务的私有属性 3 | service_description: 4 | name: TLSService -------------------------------------------------------------------------------- /tls/server/conf/tls.yaml: -------------------------------------------------------------------------------- 1 | ssl: 2 | rest.Provider.cipherPlugin: default 3 | rest.Provider.cipherSuits: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 4 | rest.Provider.protocol: TLSv1.2 5 | rest.Provider.keyFile: server.key 6 | rest.Provider.certFile: server.crt 7 | rest.Provider.certPwdFile: pwd -------------------------------------------------------------------------------- /tls/server/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/go-chassis/go-chassis/v2" 5 | "github.com/go-chassis/go-chassis/v2/core/server" 6 | "github.com/go-chassis/go-chassis/v2/examples/schemas" 7 | "github.com/go-chassis/openlog" 8 | ) 9 | 10 | //if you use go run main.go instead of binary run, plz export CHASSIS_HOME=/{path}/{to}/rest/server/ 11 | 12 | func main() { 13 | chassis.RegisterSchema("rest", &schemas.RestFulHello{}, server.WithSchemaID("RestHelloService")) 14 | if err := chassis.Init(); err != nil { 15 | openlog.Error("Init failed." + err.Error()) 16 | return 17 | } 18 | chassis.Run() 19 | } 20 | -------------------------------------------------------------------------------- /tls/server/pwd: -------------------------------------------------------------------------------- 1 | change -------------------------------------------------------------------------------- /tls/server/server.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICWDCCAcGgAwIBAgIJALU3kJeFqTthMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV 3 | BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX 4 | aWRnaXRzIFB0eSBMdGQwHhcNMTkwMjI2MDQ0MTEzWhcNMjkwMjIzMDQ0MTEzWjBF 5 | MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50 6 | ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB 7 | gQDA9TLWYKqmTI/jLqP1LP82n0OD/lC8TQqzS/GNRdZUEBKk/N9yoU9x7APUPFud 8 | hcJuTevgAklqNIHiJUQNB3/C5UkcKE4JbdqI71PtXvWH249rb9wjoQahhtGgjdmK 9 | 3A7N614X5ff04H3sRmAC12Q6itNO2ca9WDFbrDUotLS25QIDAQABo1AwTjAdBgNV 10 | HQ4EFgQU7880r5Q1fHhvEW27PqzhLQjSDhowHwYDVR0jBBgwFoAU7880r5Q1fHhv 11 | EW27PqzhLQjSDhowDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOBgQA7Busc 12 | Vw5Hnqs1lqjah8sXUH+So+6GQXYTf5kEv9IxuY2zseRIQH3iO9LQIBiwIwBrUeNf 13 | tgpY28mfVk9V4a+ps2PAlrOypEh7sC/Dh3KC27efEcUffuSHGgV4SjhA1AdqjJCH 14 | vURc3cUJ5u2oDy/oGLK2si7OcJTRF9An/0qexQ== 15 | -----END CERTIFICATE----- 16 | -------------------------------------------------------------------------------- /tls/server/server.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | Proc-Type: 4,ENCRYPTED 3 | DEK-Info: DES-EDE3-CBC,88494FBC7A9FD2BB 4 | 5 | dAb6aAZJTEN59o75NAxchvDUoUlObheD1+OufpXaoO6I95PZeVPhT5SGIgagKimW 6 | 8GOKGpV6JDRu0ilAtWMfoJH7F/xNnfKDliL/mz6FDfUKdwoWW+FUZf0NnETR3bZI 7 | 29GfG0Kgj3ni8OpkWvHsQK7EhywBMEvXz1Z1SWGeaHPv32cQU9fjuvIpEFuezyFs 8 | nXivtVjH6QcVpzQmgCS4FcEyssNPbs82w79h23/FKSe7bk91uT6ZJ6h+EPwXG53f 9 | 1RauxiQcwX6t/9um5VcyeFYsmv+gJSaySh43Q8gn9w/ZbWURzCgtMDu2T62zPF7b 10 | kKCpmzDBFSeKzbL7OG+0329XOgc68Bk349pWWMa2iiBtCeIDj+tR3V/dKQYrodzF 11 | 5Ols7rlTYEGLybkD24+2z66PofWS08FHu59xtGR1mp2TwbLdobnNFI1H1Q+1mX6H 12 | Ek25RTXGwoZGM1b50W0TZJmf7ZdM5vzOB7Qi1r+m7gbhKGcL+xJ4hhWFBuDTQ1Gl 13 | pLWhMHswKoK0OBx4Ijufm8Qufb8ViF+Q8Nr3JMYhEva3na76TA/7OiJLvffKtt3n 14 | jgZZx6K8jxZu0ypoh2mpVLEqQIDguvkMc6sEfX3RMUV2HXt2Z/j9UH9rN9P/4uc3 15 | 94lFwmyWUS+ACJDVekxgSTB/fBQtlxEEXbgoCPFyPdp7ZgqfnU+3KEE25ulq9NiV 16 | JDzfRoa3UpKJ6Lcg2p1r9UNsRnW2Xo7On5K/eWRpL3EU+eJ9HS+5Ep8V/qOzySD6 17 | kD9TdJ2xrBeieeOfP7KXh7YwOpbMBuqnyxVlMKQzDqgyPiV2lfBhlA== 18 | -----END RSA PRIVATE KEY----- 19 | --------------------------------------------------------------------------------