├── control ├── istio │ └── panel.go ├── options.go ├── servicecomb │ ├── cache.go │ ├── qps_event_listener_test.go │ ├── loadbalance_event_listener.go │ ├── event_register.go │ ├── loadbalance_event_listener_test.go │ ├── lager_event_listener_test.go │ └── qps_event_listener.go └── strcut.go ├── core ├── config │ ├── router_config_test.go │ ├── model │ │ ├── control.go │ │ ├── apm.go │ │ ├── fault_injection.go │ │ └── registry.go │ ├── route_config.go │ ├── key_generator_test.go │ ├── cd_config.go │ ├── archaius_test.go │ ├── struct_test.go │ ├── sr_config.go │ └── archaius.go ├── tracing │ ├── tracing.go │ └── tracer_manager_test.go ├── registry │ ├── options.go │ ├── servicecenter │ │ └── util_test.go │ ├── struct_test.go │ └── endpoint_struct_test.go ├── metadata │ ├── framework.go │ ├── framework_metadata_test.go │ └── framework_metadata.go ├── server │ ├── server.go │ └── options.go ├── client │ ├── client_plugins.go │ └── client.go ├── provider │ └── provider.go ├── loadbalancer │ ├── strategy.go │ ├── struct.go │ ├── randam.go │ └── struct_test.go ├── fault │ ├── fault_injection_test.go │ ├── fault.go │ └── README.md ├── governance │ └── process_test.go ├── lager │ └── lager_test.go ├── router │ └── router_config_test.go ├── marker │ ├── operator.go │ └── operator_test.go └── endpoint │ └── endpoint.go ├── NOTICE ├── logo.png ├── examples ├── metadata │ ├── conf │ │ ├── microservice.yaml │ │ ├── chassis.yaml │ │ └── lager.yaml │ ├── main.go │ └── resource │ │ ├── restful_hello.go │ │ └── handler.go ├── circuit │ ├── client │ │ └── conf │ │ │ ├── microservice.yaml │ │ │ ├── chassis.yaml │ │ │ ├── monitoring.yaml │ │ │ └── circuit_breaker.yaml │ ├── server │ │ ├── conf │ │ │ ├── microservice.yaml │ │ │ ├── chassis.yaml │ │ │ └── monitoring.yaml │ │ ├── main.go │ │ └── resource │ │ │ └── restful_hello.go │ └── README.md ├── marker │ ├── conf │ │ ├── microservice.yaml │ │ └── chassis.yaml │ └── main.go ├── ratelimit │ ├── conf │ │ ├── microservice.yaml │ │ └── chassis.yaml │ └── main.go ├── rest │ ├── client │ │ ├── conf │ │ │ ├── microservice.yaml │ │ │ └── chassis.yaml │ │ └── main.go │ ├── server │ │ ├── conf │ │ │ ├── microservice.yaml │ │ │ └── chassis.yaml │ │ └── main.go │ └── README.md ├── mutiports │ ├── server │ │ ├── conf │ │ │ ├── microservice.yaml │ │ │ └── chassis.yaml │ │ └── main.go │ └── client │ │ └── conf │ │ ├── microservice.yaml │ │ └── chassis.yaml ├── pilot │ ├── client │ │ ├── conf │ │ │ ├── microservice.yaml │ │ │ ├── router.yaml │ │ │ ├── rate_limiting.yaml │ │ │ ├── load_balancing.yaml │ │ │ ├── tls.yaml │ │ │ ├── circuit_breaker.yaml │ │ │ ├── lager.yaml │ │ │ └── chassis.yaml │ │ ├── build │ │ │ ├── Dockerfile │ │ │ ├── build_image.sh │ │ │ ├── build.sh │ │ │ └── start.sh │ │ └── main.go │ └── server │ │ ├── conf │ │ ├── microservice.yaml │ │ ├── monitoring.yaml │ │ ├── circuit_breaker.yaml │ │ ├── lager.yaml │ │ └── tls.yaml │ │ ├── build │ │ ├── Dockerfile │ │ ├── build_image.sh │ │ ├── istio │ │ │ ├── destination-rule.yaml │ │ │ └── route-weight-25-25-50.yaml │ │ ├── k8s │ │ │ └── service.yaml │ │ ├── build.sh │ │ └── start.sh │ │ └── main.go ├── jwt │ ├── conf │ │ ├── microservice.yaml │ │ └── chassis.yaml │ └── README.md ├── discovery │ ├── client │ │ ├── conf │ │ │ ├── microservice.yaml │ │ │ ├── rate_limiting.yaml │ │ │ ├── monitoring.yaml │ │ │ ├── tls.yaml │ │ │ ├── load_balancing.yaml │ │ │ ├── router.yaml │ │ │ ├── chassis.yaml │ │ │ ├── lager.yaml │ │ │ └── circuit_breaker.yaml │ │ └── build │ │ │ ├── Dockerfile │ │ │ ├── build_image.sh │ │ │ ├── build.sh │ │ │ └── start.sh │ └── server │ │ ├── conf │ │ ├── microservice.yaml │ │ ├── monitoring.yaml │ │ ├── lager.yaml │ │ ├── tls.yaml │ │ └── circuit_breaker.yaml │ │ ├── build │ │ ├── Dockerfile │ │ ├── build_image.sh │ │ ├── build.sh │ │ └── start.sh │ │ └── main.go ├── fileupload │ ├── client │ │ └── conf │ │ │ ├── chassis.yaml │ │ │ └── microservice.yaml │ └── server │ │ ├── conf │ │ ├── microservice.yaml │ │ └── chassis.yaml │ │ └── main.go ├── template │ ├── flowcontrol.yaml │ └── match-user-jason.yaml ├── watcher │ └── README.md ├── schemas │ ├── employ │ │ └── employ.proto │ ├── highway_hello.go │ └── tracing_hello.go └── db.js ├── docs ├── img │ └── logo.png ├── intro │ ├── how.png │ ├── protocol.PNG │ ├── registry.PNG │ ├── how-it-works.rst │ ├── concepts.rst │ └── what-is.md ├── user-guides │ ├── tls.png │ ├── images │ │ ├── Employ.png │ │ ├── helloservice.png │ │ ├── microservice.png │ │ ├── EmployeeStruct.png │ │ └── AddAndShowEmployee.png │ ├── dynamic-conf.md │ ├── java-call-go.md │ ├── env.md │ ├── log.md │ ├── service-discovery.md │ ├── healthz.md │ ├── filter.md │ └── profile.md ├── design-guides │ ├── images │ │ └── CC-Plugin.png │ └── cc-plugin.rst ├── dev-guides.rst ├── middleware.rst ├── get-started.rst ├── protocol-plugins.rst ├── design-guides.rst ├── plugin-tracing-guides.rst ├── intro.rst ├── control-plane.rst ├── control-plane │ ├── discovery.rst │ ├── cse.md │ └── kube-discovery.md ├── protocol-plugins │ └── rest-plugin.md ├── dev-guides │ ├── bootstrap.md │ ├── metrics.md │ ├── circuit.md │ ├── how-to-extend-protocol.md │ ├── router.md │ └── backends.md ├── README.md ├── middleware │ ├── basic-auth.md │ ├── access-log.md │ └── rate-limiting.md ├── Makefile ├── user-guides.rst ├── index.rst ├── make.bat ├── getstarted │ └── install.md └── plugins-tracing │ └── zipkin.md ├── licenses ├── NOTICE_matttproud_golang_protobuf_extensions ├── NOTICE_go-mesh_openlogging ├── NOTICE_prometheus_client_model ├── NOTICE_prometheus_common ├── NOTICE_prometheus_procfs ├── NOTICE_gopkg.in_yaml.v2 ├── LICENSE_davecgh_go-spew ├── NOTICE_prometheus_client_golang ├── LICENSE_jtolds_gls ├── COPYING_alecthomas_units ├── LICENSE_beorn7_perks ├── LICENSE_spf13_cast ├── LICENSE_cenkalti_backoff ├── LICENSE_json-iterator_go ├── LICENSE.md_go-stack_stack ├── LICENSE_emicklei_go-restful ├── LICENSE_konsorten_go-windows-terminal-sequences ├── LICENSE_go-kit_kit ├── LICENSE_go-logfmt_logfmt ├── LICENSE_sirupsen_logrus ├── LICENSE_go-chassis_go-restful-swagger20 ├── LICENSE_go.uber.org_ratelimit ├── LICENSE_stretchr_testify ├── LICENSE_patrickmn_go-cache ├── LICENSE_opentracing_opentracing-go ├── LICENSE_stretchr_objx ├── Readme_kr_logfmt ├── LICENSE.md_smartystreets_goconvey └── LICENSE_gopherjs_gopherjs ├── scripts ├── ci │ ├── start_latest_sc.sh │ ├── goConstChecker.sh │ ├── misspellChecker.sh │ ├── deadCodeChecker.sh │ ├── goVetChecker.sh │ ├── formatChecker.sh │ ├── goLintChecker.sh │ ├── goCycloChecker.sh │ └── unit_test.sh └── version_set.sh ├── CONTRIBUTING.md ├── pkg ├── scclient │ ├── options_test.go │ ├── README.md │ ├── util.go │ ├── load_balance_test.go │ ├── load_balance.go │ ├── options.go │ └── util_test.go ├── goplugin │ ├── plugin_enable.go │ ├── plugin_disable.go │ └── plugin.go ├── profile │ └── profile_test.go ├── backends │ └── quota │ │ └── options.go ├── runtime │ └── runtime.go └── tool │ └── debug.go ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ └── golangci-lint.yml ├── third_party └── forked │ └── afex │ └── hystrix-go │ ├── Vagrantfile │ ├── hystrix │ ├── reporter_test.go │ ├── pool.go │ ├── metrics_test.go │ ├── pool_metrics.go │ ├── pool_test.go │ ├── settings_test.go │ └── rolling │ │ └── rolling_test.go │ ├── scripts │ └── vagrant.sh │ └── LICENSE ├── middleware ├── circuit │ └── circuit_test.go └── ratelimiter │ └── qps_provider_flow_control_handler.go ├── session └── session_storage.go ├── .gitignore ├── server └── restful │ ├── api │ └── prom.go │ ├── common.go │ └── handler.go ├── configserver └── config_server_test.go ├── client └── rest │ └── restful.go ├── resilience └── retry │ └── backoff.go ├── go.mod ├── bootstrap └── bootstrap.go └── storage └── options.go /control/istio/panel.go: -------------------------------------------------------------------------------- 1 | package istio 2 | -------------------------------------------------------------------------------- /core/config/router_config_test.go: -------------------------------------------------------------------------------- 1 | package config_test 2 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | go-chassis 2 | Copyright 2017-2020 Huawei Technologies Co.,Ltd. -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoping378/go-chassis/master/logo.png -------------------------------------------------------------------------------- /examples/metadata/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | servicecomb: 2 | service: 3 | name: Server 4 | -------------------------------------------------------------------------------- /docs/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoping378/go-chassis/master/docs/img/logo.png -------------------------------------------------------------------------------- /docs/intro/how.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoping378/go-chassis/master/docs/intro/how.png -------------------------------------------------------------------------------- /examples/circuit/client/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | servicecomb: 2 | service: 3 | name: RESTClient -------------------------------------------------------------------------------- /examples/circuit/server/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | servicecomb: 2 | service: 3 | name: ErrServer -------------------------------------------------------------------------------- /examples/marker/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | servicecomb: 2 | service: 3 | name: markerDemoService -------------------------------------------------------------------------------- /examples/ratelimit/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | servicecomb: 2 | service: 3 | name: rateLimiter -------------------------------------------------------------------------------- /examples/rest/client/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | servicecomb: 2 | service: 3 | name: RESTClient -------------------------------------------------------------------------------- /examples/rest/server/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | servicecomb: 2 | service: 3 | name: RESTServer -------------------------------------------------------------------------------- /examples/mutiports/server/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | servicecomb: 2 | service: 3 | name: RESTServer -------------------------------------------------------------------------------- /examples/pilot/client/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | servicecomb: 2 | service: 3 | name: istioclient 4 | -------------------------------------------------------------------------------- /docs/intro/protocol.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoping378/go-chassis/master/docs/intro/protocol.PNG -------------------------------------------------------------------------------- /docs/intro/registry.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoping378/go-chassis/master/docs/intro/registry.PNG -------------------------------------------------------------------------------- /docs/user-guides/tls.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoping378/go-chassis/master/docs/user-guides/tls.png -------------------------------------------------------------------------------- /examples/jwt/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | servicecomb: 3 | service: 4 | name: JwtExampleService 5 | -------------------------------------------------------------------------------- /examples/mutiports/client/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | servicecomb: 3 | service: 4 | name: RESTClient -------------------------------------------------------------------------------- /examples/discovery/client/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | servicecomb: 3 | service: 4 | name: Client 5 | -------------------------------------------------------------------------------- /examples/discovery/server/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | servicecomb: 3 | service: 4 | name: Server 5 | -------------------------------------------------------------------------------- /licenses/NOTICE_matttproud_golang_protobuf_extensions: -------------------------------------------------------------------------------- 1 | Copyright 2012 Matt T. Proud (matt.proud@gmail.com) 2 | -------------------------------------------------------------------------------- /examples/pilot/server/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | servicecomb: 2 | service: 3 | name: istioserver 4 | app: pilot 5 | -------------------------------------------------------------------------------- /docs/user-guides/images/Employ.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoping378/go-chassis/master/docs/user-guides/images/Employ.png -------------------------------------------------------------------------------- /examples/fileupload/client/conf/chassis.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | servicecomb: 3 | registry: 4 | address: http://127.0.0.1:30100 5 | -------------------------------------------------------------------------------- /examples/mutiports/client/conf/chassis.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | servicecomb: 3 | registry: 4 | address: http://127.0.0.1:30100 5 | -------------------------------------------------------------------------------- /examples/rest/client/conf/chassis.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | servicecomb: 3 | registry: 4 | address: http://127.0.0.1:30100 5 | -------------------------------------------------------------------------------- /examples/fileupload/client/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | #微服务的私有属性 3 | servicecomb: 4 | service: 5 | name: FileUploadClient -------------------------------------------------------------------------------- /docs/design-guides/images/CC-Plugin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoping378/go-chassis/master/docs/design-guides/images/CC-Plugin.png -------------------------------------------------------------------------------- /docs/user-guides/images/helloservice.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoping378/go-chassis/master/docs/user-guides/images/helloservice.png -------------------------------------------------------------------------------- /docs/user-guides/images/microservice.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoping378/go-chassis/master/docs/user-guides/images/microservice.png -------------------------------------------------------------------------------- /examples/pilot/client/build/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu 2 | 3 | ADD *.tar.gz /home 4 | COPY start.sh /home 5 | 6 | CMD ["sh", "/home/start.sh"] -------------------------------------------------------------------------------- /examples/pilot/server/build/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu 2 | 3 | ADD *.tar.gz /home 4 | COPY start.sh /home 5 | 6 | CMD ["sh", "/home/start.sh"] -------------------------------------------------------------------------------- /docs/user-guides/images/EmployeeStruct.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoping378/go-chassis/master/docs/user-guides/images/EmployeeStruct.png -------------------------------------------------------------------------------- /examples/template/flowcontrol.yaml: -------------------------------------------------------------------------------- 1 | servicecomb: 2 | rateLimiting: 3 | limit-json: | 4 | match: match-user-jason 5 | quota: 5000 -------------------------------------------------------------------------------- /licenses/NOTICE_go-mesh_openlogging: -------------------------------------------------------------------------------- 1 | mesher 2 | Copyright 2018-present, Huawei 3 | 4 | This product includes software developed at 5 | Huawei. 6 | -------------------------------------------------------------------------------- /docs/user-guides/images/AddAndShowEmployee.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaoping378/go-chassis/master/docs/user-guides/images/AddAndShowEmployee.png -------------------------------------------------------------------------------- /docs/dev-guides.rst: -------------------------------------------------------------------------------- 1 | Development guides 2 | ========================= 3 | 4 | .. toctree:: 5 | :maxdepth: 4 6 | :glob: 7 | 8 | dev-guides/* 9 | -------------------------------------------------------------------------------- /docs/middleware.rst: -------------------------------------------------------------------------------- 1 | Middleware 2 | ====================================== 3 | 4 | .. toctree:: 5 | :maxdepth: 4 6 | :glob: 7 | 8 | middleware/* 9 | -------------------------------------------------------------------------------- /examples/fileupload/server/conf/microservice.yaml: -------------------------------------------------------------------------------- 1 | servicecomb: 2 | service: 3 | name: FileUploadServer 4 | properties: 5 | allowCrossApp: true -------------------------------------------------------------------------------- /control/options.go: -------------------------------------------------------------------------------- 1 | package control 2 | 3 | //Options is for initiating control panel 4 | type Options struct { 5 | Address string 6 | Infra string 7 | } 8 | -------------------------------------------------------------------------------- /docs/get-started.rst: -------------------------------------------------------------------------------- 1 | Get started 2 | ====================================== 3 | 4 | .. toctree:: 5 | :maxdepth: 4 6 | :glob: 7 | 8 | getstarted/* 9 | -------------------------------------------------------------------------------- /docs/protocol-plugins.rst: -------------------------------------------------------------------------------- 1 | Protocol plugins 2 | ========================= 3 | 4 | .. toctree:: 5 | :maxdepth: 4 6 | :glob: 7 | 8 | protocol-plugins/rest-plugin -------------------------------------------------------------------------------- /examples/discovery/client/build/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM 10.162.197.95:5000/cse-base:latest 2 | 3 | ADD *.tar.gz /home 4 | COPY start.sh /home 5 | 6 | CMD ["sh", "/home/start.sh"] -------------------------------------------------------------------------------- /examples/discovery/server/build/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM 10.162.197.95:5000/cse-base:latest 2 | 3 | ADD *.tar.gz /home 4 | COPY start.sh /home 5 | 6 | CMD ["sh", "/home/start.sh"] -------------------------------------------------------------------------------- /examples/pilot/client/conf/router.yaml: -------------------------------------------------------------------------------- 1 | servicecomb: 2 | router: 3 | infra: pilot # router rule comes from where 4 | address: http://istio-pilot.istio-system:15010 -------------------------------------------------------------------------------- /docs/design-guides.rst: -------------------------------------------------------------------------------- 1 | Design guides 2 | ========================= 3 | 4 | .. toctree:: 5 | :maxdepth: 4 6 | :glob: 7 | 8 | design-guides/cc-plugin 9 | 10 | -------------------------------------------------------------------------------- /docs/plugin-tracing-guides.rst: -------------------------------------------------------------------------------- 1 | Tracing Plugins 2 | ========================= 3 | 4 | .. toctree:: 5 | :maxdepth: 4 6 | :glob: 7 | 8 | plugins-tracing/* 9 | 10 | -------------------------------------------------------------------------------- /scripts/ci/start_latest_sc.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | docker pull servicecomb/service-center 4 | 5 | docker run -d -p 30100:30100 --name=service-center servicecomb/service-center:latest -------------------------------------------------------------------------------- /examples/discovery/client/conf/rate_limiting.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | cse: 4 | flowcontrol: 5 | Consumer: 6 | qps: 7 | enabled: true 8 | limit: 9 | Server: 100 10 | -------------------------------------------------------------------------------- /examples/pilot/client/conf/rate_limiting.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | servicecomb: 3 | flowcontrol: 4 | Consumer: 5 | qps: 6 | enabled: true 7 | limit: 8 | istioserver.RestFulHello: 100 9 | -------------------------------------------------------------------------------- /docs/intro.rst: -------------------------------------------------------------------------------- 1 | Introductions 2 | ====================================== 3 | 4 | .. toctree:: 5 | :maxdepth: 4 6 | :glob: 7 | 8 | intro/what-is 9 | intro/concepts 10 | intro/how-it-works 11 | -------------------------------------------------------------------------------- /examples/pilot/server/conf/monitoring.yaml: -------------------------------------------------------------------------------- 1 | servicecomb: 2 | metrics: 3 | apiPath: /metrics # we can also give api path having prefix "/" ,like /adas/metrics 4 | enable: true 5 | enableGoRuntimeMetrics: false -------------------------------------------------------------------------------- /licenses/NOTICE_prometheus_client_model: -------------------------------------------------------------------------------- 1 | Data model artifacts for Prometheus. 2 | Copyright 2012-2015 The Prometheus Authors 3 | 4 | This product includes software developed at 5 | SoundCloud Ltd. (http://soundcloud.com/). 6 | -------------------------------------------------------------------------------- /core/config/model/control.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | //ControlPanel define control panel config 4 | type ControlPanel struct { 5 | Infra string `yaml:"infra"` 6 | Settings map[string]string `yaml:"settings"` 7 | } 8 | -------------------------------------------------------------------------------- /licenses/NOTICE_prometheus_common: -------------------------------------------------------------------------------- 1 | Common libraries shared by Prometheus Go components. 2 | Copyright 2015 The Prometheus Authors 3 | 4 | This product includes software developed at 5 | SoundCloud Ltd. (http://soundcloud.com/). 6 | -------------------------------------------------------------------------------- /examples/pilot/client/build/build_image.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | 5 | workspace=$(cd $(dirname $0);pwd) 6 | cd $workspace 7 | 8 | IMAGE=gosdk-istio-client 9 | TAG=latest 10 | 11 | docker build -t $IMAGE:$TAG . 12 | -------------------------------------------------------------------------------- /examples/pilot/server/build/build_image.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | 5 | workspace=$(cd $(dirname $0);pwd) 6 | cd $workspace 7 | 8 | IMAGE=gosdk-istio-server 9 | TAG=latest 10 | 11 | docker build -t $IMAGE:$TAG . 12 | -------------------------------------------------------------------------------- /core/tracing/tracing.go: -------------------------------------------------------------------------------- 1 | package tracing 2 | 3 | //const for tracing 4 | const ( 5 | HTTPMethod = "http.method" 6 | HTTPPath = "http.path" 7 | HTTPStatusCode = "http.status_code" 8 | HTTPHost = "http.host" 9 | ) 10 | -------------------------------------------------------------------------------- /examples/discovery/client/build/build_image.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | 5 | workspace=$(cd $(dirname $0);pwd) 6 | cd $workspace 7 | 8 | IMAGE=gosdk-discovery-client 9 | TAG=latest 10 | 11 | docker build -t $IMAGE:$TAG . 12 | -------------------------------------------------------------------------------- /scripts/ci/goConstChecker.sh: -------------------------------------------------------------------------------- 1 | diff -u <(echo -n) <(goconst ./... | grep -v vendor | grep -v examples | grep -v third_party) 2 | if [ $? == 0 ]; then 3 | echo "No goConst problem" 4 | exit 0 5 | else 6 | echo "Has goConst Problem" 7 | exit 1 8 | fi 9 | -------------------------------------------------------------------------------- /examples/pilot/client/conf/load_balancing.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | servicecomb: 4 | loadbalance: 5 | retryEnabled: false 6 | retryOnNext: 2 7 | retryOnSame: 3 8 | backoff: 9 | kind: constant 10 | MinMs: 200 11 | MaxMs: 400 12 | 13 | -------------------------------------------------------------------------------- /scripts/ci/misspellChecker.sh: -------------------------------------------------------------------------------- 1 | diff -u <(echo -n) <(find . -type f -not -path "./vendor/*" -not -path "./third_party/*" -print0 | xargs -0 misspell) 2 | if [ $? == 0 ]; then 3 | echo "No Misspell found" 4 | exit 0 5 | else 6 | echo "Misspell found" 7 | exit 1 8 | fi 9 | -------------------------------------------------------------------------------- /docs/user-guides/dynamic-conf.md: -------------------------------------------------------------------------------- 1 | # Dynamic Configuration 2 | ## 概述 3 | 4 | go-chassis通过利用go-archaius提供动态配置管理能力,文档请参考[go-archaius](https://github.com/go-chassis/go-archaius) 5 | ## Example 6 | Complete [example](https://github.com/go-chassis/go-chassis-examples/tree/master/archaius) 7 | 8 | 9 | -------------------------------------------------------------------------------- /licenses/NOTICE_prometheus_procfs: -------------------------------------------------------------------------------- 1 | procfs provides functions to retrieve system, kernel and process 2 | metrics from the pseudo-filesystem proc. 3 | 4 | Copyright 2014-2015 The Prometheus Authors 5 | 6 | This product includes software developed at 7 | SoundCloud Ltd. (http://soundcloud.com/). 8 | -------------------------------------------------------------------------------- /scripts/ci/deadCodeChecker.sh: -------------------------------------------------------------------------------- 1 | find . -type d -not -path "./vendor/*" | xargs unused 2 | if [ $? == 0 ]; then 3 | echo "Hurray....all code's are reachable and utilised..." 4 | exit 0 5 | else 6 | echo "There are some deadcode in the project...please remove the unused code" 7 | exit 1 8 | fi 9 | -------------------------------------------------------------------------------- /docs/control-plane.rst: -------------------------------------------------------------------------------- 1 | Control panels 2 | ========================= 3 | 4 | .. toctree:: 5 | :maxdepth: 4 6 | :glob: 7 | 8 | control-plane/kube-discovery 9 | control-plane/servicecomb 10 | control-plane/cse 11 | control-plane/istio 12 | control-plane/apollo 13 | 14 | -------------------------------------------------------------------------------- /scripts/ci/goVetChecker.sh: -------------------------------------------------------------------------------- 1 | diff -u <(echo -n) <(find . -type d -not -path "./vendor/*" -not -path "./third_party/*"| xargs go vet ) 2 | if [ $? == 0 ]; then 3 | echo "Hurray....all OKAY..." 4 | exit 0 5 | else 6 | echo "There are some static issues in the project...please run go vet" 7 | exit 1 8 | fi 9 | -------------------------------------------------------------------------------- /examples/template/match-user-jason.yaml: -------------------------------------------------------------------------------- 1 | servicecomb: 2 | match: 3 | match-user-json: | 4 | headers: 5 | cookie: 6 | regex: "^(.*?;)?(user=jason)(;.*)?$" 7 | user: 8 | equal: jason 9 | apiPath: 10 | contains: "some/api" 11 | method: GET -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contribute to go chassis 2 | - Contribute to the documentations for go-chassis 3 | - Check our roadmap in wiki page, maybe you have interest on some items, you can implement it. 4 | - Fire an issue 5 | - Sharing your practice of using go chassis in your blog 6 | - Writing documents for go-chassis, check [here](docs) -------------------------------------------------------------------------------- /examples/discovery/server/build/build_image.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | 5 | workspace=$(cd $(dirname $0);pwd) 6 | cd $workspace 7 | 8 | IMAGE=gosdk-discovery-server 9 | TAG=latest 10 | 11 | docker build -t $IMAGE:$TAG . 12 | 13 | YUNLONG_IMAGE=csegosdk:latest 14 | 15 | docker tag $IMAGE:$TAG $YUNLONG_IMAGE 16 | -------------------------------------------------------------------------------- /scripts/ci/formatChecker.sh: -------------------------------------------------------------------------------- 1 | diff -u <(echo -n) <(find . -name "*.go" -not -path "./vendor/*" -not -path ".git/*" | xargs gofmt -s -d) 2 | if [ $? == 0 ]; then 3 | echo "Hurray....all code is formatted properly..." 4 | exit 0 5 | else 6 | echo "There is issues's with the code formatting....please run go fmt on your code" 7 | exit 1 8 | fi 9 | -------------------------------------------------------------------------------- /docs/control-plane/discovery.rst: -------------------------------------------------------------------------------- 1 | Discovery 2 | ====================== 3 | 4 | ---- 5 | 6 | Introduction 7 | ++++ 8 | 9 | 10 | 11 | 12 | example 13 | ++++ 14 | 15 | :: 16 | 17 | servicecomb: 18 | registry: 19 | registry: 20 | type: pilotv2 21 | address: grpc://istio-pilot.istio-system:15010 22 | 23 | -------------------------------------------------------------------------------- /scripts/ci/goLintChecker.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | diff -u <(echo -n) <(golint ./... | grep -v vendor | grep -v third_party | grep -v stutters | grep -v _test | grep -v examples | grep -v benchmark) 3 | if [ $? == 0 ]; then 4 | echo "No GoLint warnings found" 5 | exit 0 6 | else 7 | echo "GoLint Warnings found" 8 | exit 1 9 | fi 10 | -------------------------------------------------------------------------------- /examples/circuit/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:5000 8 | advertiseAddress: 127.0.0.1:5000 9 | handler: 10 | chain: 11 | Consumer: 12 | default: bizkeeper-consumer,loadbalance,transport -------------------------------------------------------------------------------- /examples/discovery/server/conf/monitoring.yaml: -------------------------------------------------------------------------------- 1 | servicecomb: 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 | collectorType: zipkin 9 | collectorTarget: http://localhost:9411/api/v1/spans -------------------------------------------------------------------------------- /docs/protocol-plugins/rest-plugin.md: -------------------------------------------------------------------------------- 1 | # Rest 2 | 3 | ## URL pattern definition 4 | * (default) Fast routing algorithm that allows static elements, regular expressions and dynamic parameters in the 5 | URL path (e.g. /meetings/{id} or /static/{subpath:*} 6 | 7 | You can see more documentations about router in [here](https://github.com/emicklei/go-restful) -------------------------------------------------------------------------------- /examples/watcher/README.md: -------------------------------------------------------------------------------- 1 | #watcher 2 | go-chassis provides watcher mechanism 3 | > 1. The discover communicates with the server-center via websocket to pull the change events of the register; 4 | > 2. It should be noted that the discover and service register use the same appid 5 | 6 | discovery: example of service discover 7 | regist: example of service register -------------------------------------------------------------------------------- /pkg/scclient/options_test.go: -------------------------------------------------------------------------------- 1 | package client_test 2 | 3 | import ( 4 | "github.com/go-chassis/go-chassis/v2/pkg/scclient" 5 | "github.com/stretchr/testify/assert" 6 | "testing" 7 | ) 8 | 9 | func TestWithGlobal(t *testing.T) { 10 | o := client.WithGlobal() 11 | opts := &client.CallOptions{} 12 | o(opts) 13 | assert.True(t, opts.WithGlobal) 14 | } 15 | -------------------------------------------------------------------------------- /examples/fileupload/server/conf/chassis.yaml: -------------------------------------------------------------------------------- 1 | servicecomb: 2 | registry: 3 | type: servicecenter 4 | scope: full 5 | autodiscovery: false 6 | address: http://127.0.0.1:30100 7 | refeshInterval : 30s 8 | watch: true 9 | protocols: 10 | rest: 11 | listenAddress: 127.0.0.1:8083 12 | advertiseAddress: 127.0.0.1:8083 -------------------------------------------------------------------------------- /examples/rest/server/conf/chassis.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | servicecomb: 3 | registry: 4 | address: http://127.0.0.1:30100 # If type is File then address will be the path of the file 5 | protocols: 6 | rest: 7 | listenAddress: "127.0.0.1:5001" 8 | handler: 9 | chain: 10 | Provider: 11 | default: tracing-provider,bizkeeper-provider -------------------------------------------------------------------------------- /scripts/ci/goCycloChecker.sh: -------------------------------------------------------------------------------- 1 | diff -u <(echo -n) <(find . -name "*.go" -not -path "./vendor/*" -not -path ".git/*" -not -path "./third_party/*" | grep -v _test | xargs gocyclo -over 16) 2 | if [ $? == 0 ]; then 3 | echo "All function has less cyclomatic complexity..." 4 | exit 0 5 | else 6 | echo "Functions/function has more cyclomatic complexity..." 7 | exit 1 8 | fi 9 | -------------------------------------------------------------------------------- /core/registry/options.go: -------------------------------------------------------------------------------- 1 | package registry 2 | 3 | import ( 4 | "crypto/tls" 5 | "time" 6 | ) 7 | 8 | // Options having micro-service parameters 9 | type Options struct { 10 | Addrs []string 11 | EnableSSL bool 12 | Timeout time.Duration 13 | TLSConfig *tls.Config 14 | Compressed bool 15 | Verbose bool 16 | Version string 17 | ConfigPath string 18 | } 19 | -------------------------------------------------------------------------------- /examples/discovery/client/conf/monitoring.yaml: -------------------------------------------------------------------------------- 1 | servicecomb: 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 | circuitMetricsConsumerNum: 10 8 | tracing: 9 | collectorType: zipkin 10 | collectorTarget: http://localhost:9411/api/v1/spans -------------------------------------------------------------------------------- /pkg/scclient/README.md: -------------------------------------------------------------------------------- 1 | ### Service-Center Client 2 | This is a service-center client which helps the microservice to interact with Service-Center 3 | for service-registration, discovery, instance registration and dependency management. 4 | 5 | This client implements all the [api's](https://rawcdn.githack.com/go-chassis/service-center/master/docs/api-docs.html) of Service-Center. 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: tianxiaoliang 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **Version of go chassis** 14 | 15 | **To Reproduce** 16 | Steps to reproduce the behavior: 17 | 18 | **Logs** 19 | -------------------------------------------------------------------------------- /examples/pilot/server/build/istio/destination-rule.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: DestinationRule 3 | metadata: 4 | name: istioserver 5 | spec: 6 | host: istioserver 7 | subsets: 8 | - name: v1 9 | labels: 10 | version: v1 11 | - name: v2 12 | labels: 13 | version: v2 14 | - name: v3 15 | labels: 16 | version: v3 -------------------------------------------------------------------------------- /examples/circuit/server/conf/chassis.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | servicecomb: 3 | registry: 4 | address: http://127.0.0.1:30100 # If type is File then address will be the path of the file 5 | protocols: 6 | rest: 7 | listenAddress: 127.0.0.1:5001 8 | advertiseAddress: 127.0.0.1:5001 9 | handler: 10 | chain: 11 | Provider: 12 | default: tracing-provider,bizkeeper-provider -------------------------------------------------------------------------------- /examples/schemas/employ/employ.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package employ; 3 | 4 | message EmployStruct { 5 | string name = 1; 6 | string phone = 2; 7 | } 8 | 9 | message EmployRequest { 10 | string name = 1; 11 | EmployStruct employ = 2; 12 | repeated EmployStruct employList = 3; 13 | } 14 | 15 | message EmployResponse { 16 | EmployStruct employ = 1; 17 | repeated EmployStruct employList = 2; 18 | } -------------------------------------------------------------------------------- /pkg/scclient/util.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "github.com/go-chassis/openlog" 5 | "net/url" 6 | ) 7 | 8 | func getProtocolMap(eps []string) map[string]string { 9 | m := make(map[string]string) 10 | for _, ep := range eps { 11 | u, err := url.Parse(ep) 12 | if err != nil { 13 | openlog.Error("url err: " + err.Error()) 14 | continue 15 | } 16 | m[u.Scheme] = u.Host 17 | } 18 | return m 19 | } 20 | -------------------------------------------------------------------------------- /examples/circuit/client/conf/monitoring.yaml: -------------------------------------------------------------------------------- 1 | servicecomb: 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 -------------------------------------------------------------------------------- /examples/pilot/server/build/k8s/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | labels: 5 | app: pilot 6 | name: istioserver 7 | name: istioserver 8 | namespace: default 9 | spec: 10 | ports: 11 | - name: http 12 | port: 8084 13 | protocol: TCP 14 | targetPort: 8084 15 | selector: 16 | app: pilot 17 | sessionAffinity: None 18 | type: ClusterIP 19 | status: 20 | loadBalancer: {} -------------------------------------------------------------------------------- /examples/circuit/server/conf/monitoring.yaml: -------------------------------------------------------------------------------- 1 | servicecomb: 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 14 | -------------------------------------------------------------------------------- /examples/pilot/client/conf/tls.yaml: -------------------------------------------------------------------------------- 1 | # ssl: 2 | # registry.Consumer.cipherPlugin: default 3 | # registry.Consumer.verifyPeer: false 4 | # registry.Consumer.cipherSuits: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 5 | # registry.Consumer.protocol: TLSv1.2 6 | # registry.Consumer.caFile: 7 | # registry.Consumer.certFile: 8 | # registry.Consumer.keyFile: 9 | # registry.Consumer.certPwdFile: 10 | -------------------------------------------------------------------------------- /examples/discovery/client/conf/tls.yaml: -------------------------------------------------------------------------------- 1 | # ssl: 2 | # registry.Consumer.cipherPlugin: default 3 | # registry.Consumer.verifyPeer: false 4 | # registry.Consumer.cipherSuits: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 5 | # registry.Consumer.protocol: TLSv1.2 6 | # registry.Consumer.caFile: 7 | # registry.Consumer.certFile: 8 | # registry.Consumer.keyFile: 9 | # registry.Consumer.certPwdFile: 10 | -------------------------------------------------------------------------------- /examples/discovery/client/conf/load_balancing.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | cse: 4 | loadbalance: 5 | Server: 6 | strategy: 7 | name: Random 8 | strategy: 9 | name: WeightedResponse 10 | sessionTimeoutInSeconds: 30 11 | retryEnabled: false 12 | retryOnNext: 2 13 | retryOnSame: 3 14 | serverListFilters: zoneaware 15 | backoff: 16 | kind: constant 17 | MinMs: 200 18 | MaxMs: 400 19 | 20 | -------------------------------------------------------------------------------- /core/config/model/apm.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | //MonitorCfg monitoring.yaml 配置项 4 | type MonitorCfg struct { 5 | ServiceComb ServiceCombStruct `yaml:"servicecomb"` 6 | } 7 | 8 | //ServiceCombStruct structure is for config of servicecomb 9 | type ServiceCombStruct struct { 10 | APM APMStruct `yaml:"apm"` 11 | } 12 | 13 | //APMStruct is for Application Performance Management 14 | type APMStruct struct { 15 | Tracing TracingStruct `yaml:"tracing"` 16 | } 17 | -------------------------------------------------------------------------------- /docs/intro/how-it-works.rst: -------------------------------------------------------------------------------- 1 | How it works 2 | ========================================= 3 | .. image:: how.png 4 | 5 | 这里解释运行时发生了什么 6 | 7 | 不同协议请求进入到各协议Server,Server将具体的协议请求转换为Invocation统一抽象模型,并传入Handler chain,在这里Chassis已经默认实现了很多的Handler,比如熔断,限流等,最终再进入Transport handler,使用具体的协议客户端传输到目标。 8 | 9 | 每次请求生成的监控数据通过http API导出的方式,由Prometheus收集处理 10 | 11 | 日志可通过扩展,输出到kafka等服务中也可使用华为公有云APM服务收集 12 | 13 | 注册中心默认对接Service center 14 | 15 | Archaius为动态配置框架,可从各种不同的source中读取配置 -------------------------------------------------------------------------------- /core/metadata/framework.go: -------------------------------------------------------------------------------- 1 | // Code generated by go-chassis/scripts/version_set.sh. DO NOT EDIT. 2 | 3 | // Package metadata provides framework info registered to registry. 4 | package metadata 5 | 6 | // constant for sdk version, name, registration component 7 | const ( 8 | SdkVersion = "v2.0.2" 9 | SdkName = "Go-Chassis" 10 | SdkRegistrationComponent = "SDK" 11 | PlatformRegistrationComponent = "PLATFORM" 12 | ) 13 | -------------------------------------------------------------------------------- /docs/dev-guides/bootstrap.md: -------------------------------------------------------------------------------- 1 | # BootstrapPlugin 2 | 3 | ### Introduction 4 | 5 | go-chassis gives your a way to load any custom plugin you write before start go chassis, so that you don't need to add code in go-chassis project 6 | 7 | you can use bootstrap plugin to load your custom logic to manipulate go-chassis modules, for example change Registry, router etc. 8 | 9 | 10 | ### Usage 11 | ```go 12 | func InstallPlugin(name string, plugin BootstrapPlugin) 13 | ``` -------------------------------------------------------------------------------- /third_party/forked/afex/hystrix-go/Vagrantfile: -------------------------------------------------------------------------------- 1 | Vagrant.configure("2") do |config| 2 | config.vm.box = "ubuntu/trusty64" 3 | config.vm.hostname = 'hystrix-go.local' 4 | 5 | config.vm.provision :shell, :path => "scripts/vagrant.sh" 6 | 7 | config.vm.synced_folder ".", "/go/src/github.com/afex/hystrix-go" 8 | 9 | config.vm.provider "virtualbox" do |v| 10 | v.cpus = 3 11 | end 12 | 13 | config.vm.network "forwarded_port", guest: 8888, host: 8888 14 | end 15 | -------------------------------------------------------------------------------- /examples/jwt/conf/chassis.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | servicecomb: 3 | registry: 4 | type: servicecenter #optional:可选zookeeper/servicecenter,zookeeper供中软使用,不配置的情况下默认为servicecenter 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:8083 9 | advertiseAddress: 127.0.0.1:8083 10 | handler: 11 | chain: 12 | Provider: 13 | default: jwt 14 | -------------------------------------------------------------------------------- /pkg/scclient/load_balance_test.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func BenchmarkRoundRobin(b *testing.B) { 8 | eps := []string{"172.0.0.1", "172.0.0.2", "172.0.0.3", "172.0.0.4", 9 | "172.0.0.5", "172.0.0.6", "172.0.0.7", "172.0.0.8", "172.0.0.9", 10 | "172.0.0.10", "172.0.0.11", "172.0.0.12"} 11 | next := RoundRobin(eps) 12 | b.ReportAllocs() 13 | b.ResetTimer() 14 | 15 | for i := 0; i < b.N; i++ { 16 | _, _ = next() 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /docs/dev-guides/metrics.md: -------------------------------------------------------------------------------- 1 | # Metrics Report Plugin 2 | 3 | ## Introduction 4 | go chassis allows you to install report plugin to receive runtime metrics 5 | 6 | ## Usage 7 | 8 | 1.Implement your reporter 9 | 10 | ```go 11 | type Reporter func(metrics.Registry) error 12 | ``` 13 | 14 | 2.Install reporter to go chassis 15 | ```go 16 | func InstallReporter(name string, reporter Reporter) error 17 | ``` 18 | 19 | after above step your plugin is able to receive go chassis runtime metrics -------------------------------------------------------------------------------- /examples/discovery/client/conf/router.yaml: -------------------------------------------------------------------------------- 1 | servicecomb: 2 | router: 3 | infra: cse # router rule comes from where 4 | #servicecomb: 5 | # routeRule: 6 | # Server: | 7 | # - precedence: 1 8 | # route: #路由规则列表 9 | # - tags: 10 | # version: 0.2.0 #对接service center的话,如果不填就自动为latest 11 | # weight: 80 #全重 80%到这里 12 | # - tags: 13 | # version: 0.1.0 #对接service center的话,如果不填就自动为latest 14 | # weight: 20 #全重 80%到这里 -------------------------------------------------------------------------------- /examples/schemas/highway_hello.go: -------------------------------------------------------------------------------- 1 | package schemas 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/go-chassis/go-chassis/v2/examples/schemas/helloworld" 7 | ) 8 | 9 | //HelloServer is a struct 10 | type HelloServer struct { 11 | } 12 | 13 | //SayHello is a method used to reply message 14 | func (s *HelloServer) SayHello(ctx context.Context, in *helloworld.HelloRequest) (*helloworld.HelloReply, error) { 15 | return &helloworld.HelloReply{Message: "Go Hello " + in.Name}, nil 16 | } 17 | -------------------------------------------------------------------------------- /examples/metadata/conf/chassis.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | servicecomb: 3 | registry: 4 | type: servicecenter #optional:可选zookeeper/servicecenter,zookeeper供中软使用,不配置的情况下默认为servicecenter 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:8083 9 | advertiseAddress: 127.0.0.1:8083 10 | handler: 11 | chain: 12 | Provider: 13 | default: metadata-handler 14 | -------------------------------------------------------------------------------- /core/server/server.go: -------------------------------------------------------------------------------- 1 | //Package server is a package for protocol of a micro service 2 | package server 3 | 4 | // ProtocolServer interface for the protocol server, a server should implement init, register, start, and stop 5 | type ProtocolServer interface { 6 | //Register a schema of microservice,return unique schema id,you can specify schema id and microservice name of this schema 7 | Register(interface{}, ...RegisterOption) (string, error) 8 | Start() error 9 | Stop() error 10 | String() string 11 | } 12 | -------------------------------------------------------------------------------- /scripts/ci/unit_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | set -x 4 | # Make the Coverage File 5 | echo "mode: atomic" > coverage.txt 6 | # Make Necessary directories needed by Test (Ideally it should get created automatically but Travis is not allowing to create it using os.MkdriAll) 7 | # I know this is insane but nothing can be done 8 | 9 | go test $(go list ./... | grep -v third_party | grep -v examples) -cover -covermode atomic -coverprofile coverage.out -timeout=30m 10 | 11 | sed '1d;$d' coverage.out >> coverage.txt 12 | -------------------------------------------------------------------------------- /core/config/route_config.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import "github.com/go-chassis/go-archaius" 4 | 5 | //DefaultRouterType set the default router type 6 | const DefaultRouterType = "cse" 7 | 8 | // GetRouterType returns the type of router 9 | func GetRouterType() string { 10 | return archaius.GetString("servicecomb.router.infra", DefaultRouterType) 11 | } 12 | 13 | // GetRouterEndpoints returns the router address 14 | func GetRouterEndpoints() string { 15 | return archaius.GetString("servicecomb.router.address", "") 16 | } 17 | -------------------------------------------------------------------------------- /.github/workflows/golangci-lint.yml: -------------------------------------------------------------------------------- 1 | name: golangci-lint 2 | on: 3 | push: 4 | tags: 5 | - v* 6 | branches: 7 | - master 8 | pull_request: 9 | jobs: 10 | golangci: 11 | name: lint 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v2 15 | - name: golangci-lint 16 | uses: golangci/golangci-lint-action@v2 17 | with: 18 | version: v1.29 19 | args: --skip-dirs=examples --out-format=colored-line-number --enable golint --skip-files=.*_test.go$ -------------------------------------------------------------------------------- /examples/metadata/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/go-chassis/go-chassis/v2" 5 | "github.com/go-chassis/go-chassis/v2/examples/metadata/resource" 6 | ) 7 | 8 | //if you use go run main.go instead of binary run, plz export CHASSIS_HOME=/{path}/{to}/discovery/server/ 9 | func main() { 10 | chassis.RegisterSchema("rest", &resource.RestFulHello{}) 11 | //start all server you register in server/schemas. 12 | if err := chassis.Init(); err != nil { 13 | panic(err) 14 | return 15 | } 16 | chassis.Run() 17 | } 18 | -------------------------------------------------------------------------------- /middleware/circuit/circuit_test.go: -------------------------------------------------------------------------------- 1 | package circuit_test 2 | 3 | import ( 4 | "errors" 5 | "testing" 6 | 7 | "github.com/go-chassis/go-chassis/v2/core/invocation" 8 | "github.com/go-chassis/go-chassis/v2/middleware/circuit" 9 | "github.com/stretchr/testify/assert" 10 | ) 11 | 12 | func TestFallbackErr(t *testing.T) { 13 | inv := &invocation.Invocation{} 14 | finish := make(chan *invocation.Response) 15 | f := circuit.FallbackErr(inv, finish) 16 | 17 | err := f(errors.New("internal error")) 18 | assert.NoError(t, err) 19 | } 20 | -------------------------------------------------------------------------------- /examples/rest/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/examples/schemas" 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", &schemas.RestFulHello{}) 13 | if err := chassis.Init(); err != nil { 14 | openlog.Fatal("Init failed." + err.Error()) 15 | return 16 | } 17 | chassis.Run() 18 | } 19 | -------------------------------------------------------------------------------- /examples/mutiports/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:5001 8 | advertiseAddress: 127.0.0.1:5001 9 | rest-legacy: 10 | listenAddress: 127.0.0.1:5002 11 | advertiseAddress: 127.0.0.1:5002 12 | rest-admin: 13 | listenAddress: 127.0.0.1:5003 14 | advertiseAddress: 127.0.0.1:5003 15 | handler: 16 | chain: 17 | Provider: 18 | default: tracing-provider,bizkeeper-provider -------------------------------------------------------------------------------- /examples/pilot/server/build/istio/route-weight-25-25-50.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: istioserver 5 | spec: 6 | hosts: 7 | - istioserver 8 | http: 9 | - route: 10 | - destination: 11 | host: istioserver 12 | subset: v1 13 | weight: 25 14 | - destination: 15 | host: istioserver 16 | subset: v2 17 | weight: 25 18 | - destination: 19 | host: istioserver 20 | subset: v3 21 | weight: 50 -------------------------------------------------------------------------------- /docs/user-guides/java-call-go.md: -------------------------------------------------------------------------------- 1 | # Java chassis 和 Go chassis互相调用 2 | 3 | 当你在一个项目中需要同时使用java和go语言时,且java语言框架为servicecomb-java-chassis, 4 | 5 | ## java chassis call go chassis 6 | 7 | 请注意,java调用go时,反序列化需要用到schema中的x-java-interface标示所需要的class,但是,go-chassis并不能帮助你生成,需要你把这个参数添加到schema中,所以,请在chassis.yaml中设定 noRefreshSchema: true,表示不会自动生成schema,否则每次启动都会被覆盖。除此之外,并不需要任何的特殊设置。 8 | 9 | 代码请参考https://github.com/go-chassis/go-chassis-examples/java-call-go 10 | 11 | ## go chassis call java chassis 12 | 13 | 当Java作为提供者时,需要注意,必须使用HTTP通信,go-chassis不支持highway协议。 14 | 除此之外,无需任何特殊配置。 15 | -------------------------------------------------------------------------------- /examples/fileupload/server/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/go-chassis/go-chassis/v2" 5 | example "github.com/go-chassis/go-chassis/v2/examples/fileupload/server/schemas" 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}/fileupload/server/ 10 | func main() { 11 | chassis.RegisterSchema("rest", &example.RestFulUpload{}) 12 | 13 | if err := chassis.Init(); err != nil { 14 | openlog.Error("Init failed." + err.Error()) 15 | return 16 | } 17 | chassis.Run() 18 | } 19 | -------------------------------------------------------------------------------- /examples/ratelimit/conf/chassis.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | servicecomb: 3 | registry: 4 | address: http://127.0.0.1:30100 # If type is File then address will be the path of the file 5 | protocols: 6 | rest: 7 | listenAddress: "127.0.0.1:5001" 8 | #advertiseAddress: "internal_ip:5001" 9 | handler: 10 | chain: 11 | Provider: 12 | default: ratelimiter-provider 13 | cse: 14 | flowcontrol: 15 | Provider: 16 | qps: 17 | enabled: true # enable rate limiting or not 18 | global: 19 | limit: 2 # default limit of provider 20 | -------------------------------------------------------------------------------- /pkg/goplugin/plugin_enable.go: -------------------------------------------------------------------------------- 1 | // +build !go1.10 !debug 2 | 3 | package goplugin 4 | 5 | import "plugin" 6 | 7 | // LoadPlugin load plugin 8 | func LoadPlugin(name string) (*plugin.Plugin, error) { 9 | path, err := LookupPlugin(name) 10 | if err != nil { 11 | return nil, err 12 | } 13 | p, err := plugin.Open(path) 14 | if err != nil { 15 | return nil, err 16 | } 17 | return p, nil 18 | } 19 | 20 | func lookUp(plugName, symName string) (interface{}, error) { 21 | p, err := LoadPlugin(plugName) 22 | if err != nil { 23 | return nil, err 24 | } 25 | return p.Lookup(symName) 26 | } 27 | -------------------------------------------------------------------------------- /examples/jwt/README.md: -------------------------------------------------------------------------------- 1 | 1.run service center 2 | 3 | 4 | 2.build and run 5 | ```go 6 | go build main.go 7 | ./main 8 | ``` 9 | 10 | 3.login to get a JWT 11 | ```sh 12 | curl -X POST \ 13 | http://127.0.0.1:8083/login \ 14 | -H 'Content-Type: application/json' \ 15 | -d '{ 16 | "name":"admin", 17 | "password":"admin" 18 | }' 19 | ``` 20 | 21 | 4.use token to request 22 | ```sh 23 | curl -X GET \ 24 | http://127.0.0.1:8083/resource \ 25 | -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwd2QiOiJhZG1pbiIsInVzZXIiOiJhZG1pbiJ9.MBKksgenh7QeZcey8MGP2IDbPqK9LS4M5LNEULl8B6o' \ 26 | ``` -------------------------------------------------------------------------------- /core/config/key_generator_test.go: -------------------------------------------------------------------------------- 1 | package config_test 2 | 3 | import ( 4 | "strings" 5 | "testing" 6 | 7 | "github.com/go-chassis/go-chassis/v2/core/common" 8 | "github.com/go-chassis/go-chassis/v2/core/config" 9 | "github.com/stretchr/testify/assert" 10 | ) 11 | 12 | func TestGetSpecificKey(t *testing.T) { 13 | cmd := strings.Join([]string{common.Consumer, "Carts"}, ".") 14 | key := config.GetHystrixSpecificKey(config.NamespaceIsolation, cmd, config.PropertyTimeoutInMilliseconds) 15 | assert.Equal(t, "cse.isolation.Consumer.Carts."+config.PropertyTimeoutInMilliseconds, key) 16 | t.Log(key) 17 | } 18 | -------------------------------------------------------------------------------- /examples/marker/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:5001" 8 | #advertiseAddress: "internal_ip:5001" 9 | handler: 10 | chain: 11 | Provider: 12 | default: traffic-marker,rate-limiter 13 | match: 14 | markGetRequest: | 15 | matches: 16 | - method: 17 | - GET 18 | apiPath: 19 | exact: "/hello" 20 | rateLimiting: 21 | limiteGet: | 22 | match: markGetRequest 23 | rate: 100 24 | burst: 20 25 | -------------------------------------------------------------------------------- /third_party/forked/afex/hystrix-go/hystrix/reporter_test.go: -------------------------------------------------------------------------------- 1 | package hystrix_test 2 | 3 | import ( 4 | "github.com/go-chassis/go-chassis/v2/third_party/forked/afex/hystrix-go/hystrix" 5 | "github.com/go-chassis/go-chassis/v2/third_party/forked/afex/hystrix-go/hystrix/reporter" 6 | "github.com/stretchr/testify/assert" 7 | "testing" 8 | ) 9 | 10 | func TestInstallReporter(t *testing.T) { 11 | err := hystrix.InstallReporter("test", reporter.ReportMetricsToPrometheus) 12 | assert.NoError(t, err) 13 | err = hystrix.InstallReporter("test", reporter.ReportMetricsToPrometheus) 14 | assert.Error(t, err) 15 | } 16 | -------------------------------------------------------------------------------- /session/session_storage.go: -------------------------------------------------------------------------------- 1 | package session 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | // Save for setting the session uuid, endpoint, timeout 8 | func Save(sid string, ep string, timeOut time.Duration) { 9 | Cache.Set(sid, ep, timeOut) 10 | } 11 | 12 | // Get return endpoint based on session uuid 13 | func Get(sid string) (ep interface{}, ok bool) { 14 | ep, ok = Cache.Get(sid) 15 | return 16 | } 17 | 18 | //ClearExpired delete all expired session 19 | func ClearExpired() { 20 | Cache.DeleteExpired() 21 | } 22 | 23 | // Delete delete the session uuid 24 | func Delete(sid string) { 25 | Cache.Delete(sid) 26 | } 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode/* 2 | !.vscode/settings.json 3 | !.vscode/tasks.json 4 | !.vscode/launch.json 5 | !.vscode/extensions.json 6 | 7 | bin/ 8 | .idea/ 9 | **/log/chassis.log 10 | *.exe 11 | *.log 12 | *.zip 13 | *.lnk 14 | 15 | release 16 | *.tar.gz 17 | glide.lock 18 | 19 | vendor/** 20 | !vendor/manifest 21 | docs/_build 22 | examples/**/*.yaml 23 | benchmark/**/*.csv 24 | benchmark/**/*.txt 25 | benchmark/client/client 26 | benchmark/server/server 27 | benchmark/**/log 28 | coverage.out 29 | coverage.txt 30 | core/lager*.copy 31 | core/config/*.yaml 32 | main 33 | auth.yaml 34 | git rm examples/discovery/*/conf/*/schema/*.yaml -------------------------------------------------------------------------------- /examples/circuit/client/conf/circuit_breaker.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | cse: 3 | isolation: 4 | Consumer: 5 | timeoutInMilliseconds: 100 6 | maxConcurrentRequests: 1000 7 | circuitBreaker: 8 | scope: api # service|api 9 | Consumer: 10 | enabled: true 11 | forceOpen: false 12 | forceClosed: false 13 | sleepWindowInMilliseconds: 10000 14 | requestVolumeThreshold: 10 15 | errorThresholdPercentage: 10 16 | #容错处理函数,目前暂时按照开源的方式来不进行区分处理,统一调用fallback函数 17 | fallback: 18 | Consumer: 19 | enabled: true 20 | fallbackpolicy: 21 | Consumer: 22 | policy: throwexception -------------------------------------------------------------------------------- /examples/pilot/client/conf/circuit_breaker.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | servicecomb: 3 | isolation: 4 | Consumer: 5 | timeoutInMilliseconds: 1000 6 | maxConcurrentRequests: 100 7 | circuitBreaker: 8 | Consumer: 9 | enabled: true 10 | forceOpen: false 11 | forceClosed: false 12 | sleepWindowInMilliseconds: 1000 13 | requestVolumeThreshold: 20 14 | errorThresholdPercentage: 10 15 | #容错处理函数,目前暂时按照开源的方式来不进行区分处理,统一调用fallback函数 16 | fallback: 17 | Consumer: 18 | enabled: true 19 | maxConcurrentRequests: 20 20 | fallbackpolicy: 21 | Consumer: 22 | policy: throwexception -------------------------------------------------------------------------------- /licenses/NOTICE_gopkg.in_yaml.v2: -------------------------------------------------------------------------------- 1 | Copyright 2011-2016 Canonical Ltd. 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 | -------------------------------------------------------------------------------- /examples/rest/README.md: -------------------------------------------------------------------------------- 1 | Simple Rest service 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 rest server 8 | 9 | ```sh 10 | cd examples/rest/server 11 | export CHASSIS_HOME=$PWD 12 | go run main.go 13 | 14 | ``` 15 | 16 | 3.Run Rest client 17 | ```sh 18 | cd examples/rest/client 19 | export CHASSIS_HOME=$PWD 20 | go run main.go 21 | 22 | 23 | ``` 24 | 25 | you can find rest api doc in local, in the meantime it is uploaded automatically to service center. 26 | ```shell 27 | vim conf/RESTServer/schema/RESTServer.yaml 28 | ``` 29 | -------------------------------------------------------------------------------- /core/config/model/fault_injection.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import "time" 4 | 5 | // FaultProtocolStruct fault protocol struct 6 | type FaultProtocolStruct struct { 7 | Fault map[string]Fault `yaml:"protocols"` 8 | } 9 | 10 | // Fault fault struct 11 | type Fault struct { 12 | Abort Abort `yaml:"abort"` 13 | Delay Delay `yaml:"delay"` 14 | } 15 | 16 | // Abort abort struct 17 | type Abort struct { 18 | Percent int `yaml:"percent"` 19 | HTTPStatus int `yaml:"httpStatus"` 20 | } 21 | 22 | // Delay delay struct 23 | type Delay struct { 24 | Percent int `yaml:"percent"` 25 | FixedDelay time.Duration `yaml:"fixedDelay"` 26 | } 27 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # How to write doc in local 2 | 3 | ## Prepare 4 | 1. Install Python 2.7 with zlib, libssl-dev(openssl-devel) 5 | 1. Install pip 6 | 1. Install readthe doc support https://docs.readthedocs.io/en/latest/getting_started.html 7 | 1. Install RTD module 8 | ```shell 9 | sudo pip install sphinx_rtd_theme 10 | ``` 11 | 12 | ## Generate doc 13 | 14 | In windows 15 | ```shell 16 | pip install recommonmark 17 | cd docs 18 | make.bat html 19 | ``` 20 | 21 | In linux 22 | ```shell 23 | cd docs 24 | sphinx-autobuild . _build/html 25 | ``` 26 | 27 | ## Check the result 28 | 29 | 1. See html pages in _build folder 30 | 1. Access http://127.0.0.1:8000 31 | -------------------------------------------------------------------------------- /docs/middleware/basic-auth.md: -------------------------------------------------------------------------------- 1 | # Basic Auth 2 | go chassis提供高级别通用中间件抽象层,其中的一个抽象是Basic Auth,免于用户学习[handler chain内部的复杂性](https://go-chassis.readthedocs.io/dev-guides/how-to-implement-handler.html),让用户只需关注与自身业务的开发 3 | 4 | ## 使用 5 | 编写业务代码 6 | ```go 7 | basicauth.Use(&basicauth.BasicAuth{ 8 | Realm: "test-realm", 9 | Authenticate: func(user, password string) error { 10 | //check your user name and password 11 | return nil 12 | }, 13 | }) 14 | ``` 15 | 更改配置文件, 将basicAuth handler添加到chain中,注意作为认证鉴权,一般说的都是服务端功能,所以要放到provider chain中 16 | ```yaml 17 | servicecomb: 18 | handler: 19 | chain: 20 | Provider: 21 | default: basicAuth 22 | ``` -------------------------------------------------------------------------------- /examples/circuit/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/circuit/server/resource" 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", &resource.RestFulMessage{}, 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 | -------------------------------------------------------------------------------- /examples/mutiports/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/examples/schemas" 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", &schemas.Hello{}) 13 | chassis.RegisterSchema("rest-legacy", &schemas.Legacy{}) 14 | chassis.RegisterSchema("rest-admin", &schemas.Admin{}) 15 | if err := chassis.Init(); err != nil { 16 | openlog.Error("Init failed." + err.Error()) 17 | return 18 | } 19 | chassis.Run() 20 | } 21 | -------------------------------------------------------------------------------- /examples/pilot/server/conf/circuit_breaker.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | servicecomb: 3 | isolation: 4 | Consumer: 5 | timeoutInMilliseconds: 10 6 | maxConcurrentRequests: 100 7 | Provider: 8 | timeoutInMilliseconds: 20 9 | maxConcurrentRequests: 200 10 | circuitBreaker: 11 | Consumer: 12 | enabled: true 13 | forceOpen: false 14 | forceClose: false 15 | sleepWindowInMilliseconds: 10000 16 | requestVolumeThreshold: 20 17 | errorThresholdPercentage: 50 18 | fallback: 19 | Consumer: 20 | enabled: true 21 | maxConcurrentRequests: 20 22 | fallbackpolicy: 23 | Consumer: 24 | policy: throwexception -------------------------------------------------------------------------------- /pkg/goplugin/plugin_disable.go: -------------------------------------------------------------------------------- 1 | // +build go1.10,debug 2 | 3 | // Add -tags debug into go build arguments before debugging, 4 | // if your go version is go1.10 onward. 5 | // example: go build -tags debug -o server -gcflags "all=-N -l" server.go 6 | // Chassis customized debug tag to resolve dlv debug issue: 7 | // https://github.com/golang/go/issues/23733 8 | // https://github.com/derekparker/delve/issues/865 9 | 10 | package goplugin 11 | 12 | import ( 13 | "errors" 14 | ) 15 | 16 | var errGoPluginDisabled = errors.New("plugin is disabled by build tag: debug") 17 | 18 | func lookUp(plugName, symName string) (interface{}, error) { 19 | return nil, errGoPluginDisabled 20 | } 21 | -------------------------------------------------------------------------------- /docs/design-guides/cc-plugin.rst: -------------------------------------------------------------------------------- 1 | Config Client Plugin 2 | ==================== 3 | 4 | Config Client 5 | ############# 6 | Go-Chassis provides the functionality to pull the configs from different config-centers, to keep the go-chassis extensible to support multiple config-center this Client was implemented as a plugin. 7 | 8 | More Details of the plugin can be found `here <../dev-guides/archaius-config-source-plugin>`_ 9 | 10 | Currently Go-Chassis has two implementation of this plugin for Huawei Config-Center and Ctrip Apollo Config-Center. 11 | 12 | Basic Sequence diagram for this plugin is given below. 13 | 14 | .. image:: images/CC-Plugin.png 15 | :alt: CC Plugin Sequence Diagram -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | SPHINXPROJ = go-chassis 8 | SOURCEDIR = . 9 | BUILDDIR = _build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -------------------------------------------------------------------------------- /pkg/scclient/load_balance.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "errors" 5 | "math/rand" 6 | "sync/atomic" 7 | ) 8 | 9 | // ErrNoneAvailable create a new error with Message No available 10 | var ErrNoneAvailable = errors.New("no available") 11 | 12 | // Next gives the next object in the list 13 | type Next func() (string, error) 14 | 15 | var i = rand.Int31() 16 | 17 | // RoundRobin Gives the next object in sequence 18 | func RoundRobin(eps []string) Next { 19 | return func() (string, error) { 20 | if len(eps) == 0 { 21 | return "", ErrNoneAvailable 22 | } 23 | node := eps[int(atomic.LoadInt32(&i))%len(eps)] 24 | atomic.AddInt32(&i, 1) 25 | return node, nil 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /docs/user-guides/env.md: -------------------------------------------------------------------------------- 1 | # Supported Environments 2 | This shows environments that go-chassis supports, 3 | you can control the value by setting environment 4 | 5 | **HOSTING_SERVER_IP** 6 | > the IP of a VM, will be added into the metadata of instance 7 | 8 | **SCHEMA_ROOT** 9 | > where to read the schema files, 10 | the path format is {SCHEMA_ROOT}/{SERVICE_NAME}/{schema_id}.yaml 11 | 12 | **CAS_COMPONENT_NAME** 13 | > service name registered to service center 14 | 15 | **CAS_INSTANCE_VERSION** 16 | > version registered to service center 17 | 18 | **CAS_APPLICATION_NAME** 19 | > app registered to service center 20 | 21 | **PAAS_CSE_ENDPOINT** 22 | > address of config center and service center 23 | -------------------------------------------------------------------------------- /examples/discovery/client/build/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | 5 | appname="gosdk-discovery-client" 6 | 7 | BUILD_PATH=$(cd $(dirname $0);pwd) 8 | ROOT_PATH=$(cd $BUILD_PATH/..;pwd) 9 | RELEASE_PATH=$ROOT_PATH/release 10 | 11 | cd $ROOT_PATH 12 | 13 | mkdir -p $RELEASE_PATH/$appname 14 | rm -rf $RELEASE_PATH/* 15 | 16 | go build -a -o "$RELEASE_PATH/$appname/app" 17 | 18 | cp -rf conf $RELEASE_PATH/$appname 19 | if [ -d "lib" ]; then 20 | cp -rf lib $RELEASE_PATH/$appname 21 | fi 22 | 23 | cd $RELEASE_PATH 24 | 25 | package=$appname.tar.gz 26 | tar -zcvf $package $appname 27 | 28 | cp $RELEASE_PATH/$package $BUILD_PATH 29 | bash $BUILD_PATH/build_image.sh 30 | 31 | echo "build success!" 32 | -------------------------------------------------------------------------------- /examples/discovery/server/build/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | 5 | appname="gosdk-discovery-server" 6 | 7 | BUILD_PATH=$(cd $(dirname $0);pwd) 8 | ROOT_PATH=$(cd $BUILD_PATH/..;pwd) 9 | RELEASE_PATH=$ROOT_PATH/release 10 | 11 | cd $ROOT_PATH 12 | 13 | mkdir -p $RELEASE_PATH/$appname 14 | rm -rf $RELEASE_PATH/* 15 | 16 | go build -a -o "$RELEASE_PATH/$appname/app" 17 | 18 | cp -rf conf $RELEASE_PATH/$appname 19 | if [ -d "lib" ]; then 20 | cp -rf lib $RELEASE_PATH/$appname 21 | fi 22 | 23 | cd $RELEASE_PATH 24 | 25 | package=$appname.tar.gz 26 | tar -zcvf $package $appname 27 | 28 | cp $RELEASE_PATH/$package $BUILD_PATH 29 | bash $BUILD_PATH/build_image.sh 30 | 31 | echo "build success!" 32 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /server/restful/api/prom.go: -------------------------------------------------------------------------------- 1 | //Package api supply a bunch of common http handler that could be mounted on you rest server and expose ability 2 | // for example: prometheus metrics will be exported on /metrics api 3 | package api 4 | 5 | import ( 6 | "github.com/emicklei/go-restful" 7 | "github.com/go-chassis/go-chassis/v2/pkg/metrics" 8 | "github.com/prometheus/client_golang/prometheus/promhttp" 9 | ) 10 | 11 | // PrometheusHandleFunc is a go-restful handler which can expose metrics in http server 12 | func PrometheusHandleFunc(req *restful.Request, rep *restful.Response) { 13 | promhttp.HandlerFor(metrics.GetSystemPrometheusRegistry(), promhttp.HandlerOpts{}).ServeHTTP(rep.ResponseWriter, req.Request) 14 | } 15 | -------------------------------------------------------------------------------- /core/client/client_plugins.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "fmt" 5 | "github.com/go-chassis/openlog" 6 | ) 7 | 8 | // NewFunc is function for the client 9 | type NewFunc func(Options) (ProtocolClient, error) 10 | 11 | var plugins = make(map[string]NewFunc) 12 | 13 | // GetClientNewFunc is to get the client 14 | func GetClientNewFunc(name string) (NewFunc, error) { 15 | f := plugins[name] 16 | if f == nil { 17 | return nil, fmt.Errorf("don't have client plugin %s", name) 18 | } 19 | return f, nil 20 | } 21 | 22 | // InstallPlugin is plugin for the new function 23 | func InstallPlugin(protocol string, f NewFunc) { 24 | openlog.Info("Install client plugin, protocol: " + protocol) 25 | plugins[protocol] = f 26 | } 27 | -------------------------------------------------------------------------------- /examples/pilot/client/build/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | 5 | appname="gosdk-istio-client" 6 | 7 | BUILD_PATH=$(cd $(dirname $0);pwd) 8 | ROOT_PATH=$(cd $BUILD_PATH/..;pwd) 9 | RELEASE_PATH=$ROOT_PATH/release 10 | 11 | cd $ROOT_PATH 12 | 13 | mkdir -p $RELEASE_PATH/$appname 14 | rm -rf $RELEASE_PATH/* 15 | 16 | go build --ldflags " -extldflags '-static'" -a -o "$RELEASE_PATH/$appname/app" 17 | 18 | cp -rf conf $RELEASE_PATH/$appname 19 | if [ -d "lib" ]; then 20 | cp -rf lib $RELEASE_PATH/$appname 21 | fi 22 | 23 | cd $RELEASE_PATH 24 | 25 | package=$appname.tar.gz 26 | tar -zcvf $package $appname 27 | 28 | cp $RELEASE_PATH/$package $BUILD_PATH 29 | bash $BUILD_PATH/build_image.sh 30 | 31 | echo "build success!" 32 | -------------------------------------------------------------------------------- /examples/pilot/server/build/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | 5 | appname="gosdk-istio-server" 6 | 7 | BUILD_PATH=$(cd $(dirname $0);pwd) 8 | ROOT_PATH=$(cd $BUILD_PATH/..;pwd) 9 | RELEASE_PATH=$ROOT_PATH/release 10 | 11 | cd $ROOT_PATH 12 | 13 | mkdir -p $RELEASE_PATH/$appname 14 | rm -rf $RELEASE_PATH/* 15 | 16 | go build --ldflags " -extldflags '-static'" -a -o "$RELEASE_PATH/$appname/app" 17 | 18 | cp -rf conf $RELEASE_PATH/$appname 19 | if [ -d "lib" ]; then 20 | cp -rf lib $RELEASE_PATH/$appname 21 | fi 22 | 23 | cd $RELEASE_PATH 24 | 25 | package=$appname.tar.gz 26 | tar -zcvf $package $appname 27 | 28 | cp $RELEASE_PATH/$package $BUILD_PATH 29 | bash $BUILD_PATH/build_image.sh 30 | 31 | echo "build success!" 32 | -------------------------------------------------------------------------------- /docs/intro/concepts.rst: -------------------------------------------------------------------------------- 1 | Concepts 2 | =================== 3 | Registry 4 | A registry must support both registration and discovery 5 | 6 | Registrator 7 | A registrator service must support registration 8 | 9 | Service Discovery 10 | A Service Discovery service must support discovery service at least. 11 | For example,ServiceComb service center support both registration and discovery 12 | Istio and kubernetes only support discovery 13 | 14 | .. image:: registry.PNG 15 | 16 | 17 | Protocol server and client 18 | go chassis allows you to integrate any protocol into standardized model Invocation, so that any protocol can reuse same function like circuit breaker, load balancing, rate limiting, route management 19 | 20 | .. image:: protocol.PNG -------------------------------------------------------------------------------- /examples/discovery/server/conf/lager.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | logWriters: file,stdout 3 | # LoggerLevel: |DEBUG|INFO|WARN|ERROR|FATAL 4 | logLevel: DEBUG 5 | 6 | # LoggerFile: used to output the name of log.可配置绝对路径,也可以配置用于拼接CHASSIS_HOME的相对路径。 7 | logFile: log/chassis.log 8 | 9 | # LogFormatText:设定日志的输出格式是 json 还是 plaintext (类似于log4j),默认为 false,不建议修改,如果开发过程中想本地查看日志的话, 10 | # 可以设定 LoggerFile 和 LogFormatText 为 true,这样会输出类似于 log4j 格式的本地日志。 11 | logFormatText: false 12 | 13 | 14 | # MaxDaily of a log file before rotate. By D Days.;日志rotate时间配置,单位"day"。 15 | logRotateAge: 1 16 | 17 | # MaxSize of a log file before rotate. By M Bytes.;日志rotate文件大小配置,单位"MB"。 18 | logRotateSize: 10 19 | 20 | # Max counts to keep of a log's backup files.日志最大存储数量,单位“个”。 21 | logBackupCount: 7 -------------------------------------------------------------------------------- /docs/user-guides.rst: -------------------------------------------------------------------------------- 1 | User guides 2 | ========================= 3 | 4 | .. toctree:: 5 | :maxdepth: 4 6 | :glob: 7 | 8 | user-guides/microservice 9 | user-guides/registry 10 | user-guides/service-discovery 11 | user-guides/protocols 12 | user-guides/handler-chain 13 | user-guides/marker 14 | user-guides/healthz 15 | user-guides/invoker 16 | user-guides/strategy 17 | user-guides/filter 18 | user-guides/dynamic-conf 19 | user-guides/router 20 | user-guides/fault-tolerance 21 | user-guides/transport 22 | user-guides/tracing 23 | user-guides/metrics 24 | user-guides/profile 25 | user-guides/log 26 | user-guides/tls 27 | user-guides/contract 28 | user-guides/env 29 | user-guides/java-call-go 30 | -------------------------------------------------------------------------------- /examples/pilot/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/bootstrap" 6 | _ "github.com/go-chassis/go-chassis/v2/configserver" 7 | "github.com/go-chassis/go-chassis/v2/examples/schemas" 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/conf/folder 12 | func main() { 13 | chassis.RegisterSchema("rest", &schemas.RestFulHello{}) 14 | chassis.RegisterSchema("rest", &schemas.RestFulMessage{}) 15 | //start all server you register in server/schemas. 16 | if err := chassis.Init(); err != nil { 17 | openlog.Error("Init failed." + err.Error()) 18 | return 19 | } 20 | chassis.Run() 21 | } 22 | -------------------------------------------------------------------------------- /third_party/forked/afex/hystrix-go/scripts/vagrant.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | wget -q https://storage.googleapis.com/golang/go1.6.2.linux-amd64.tar.gz 5 | tar -C /usr/local -xzf go1.6.2.linux-amd64.tar.gz 6 | 7 | apt-get update 8 | apt-get -y install git mercurial apache2-utils 9 | 10 | echo 'export PATH=$PATH:/usr/local/go/bin:/go/bin 11 | export GOPATH=/go' >> /home/vagrant/.profile 12 | 13 | source /home/vagrant/.profile 14 | 15 | go get golang.org/x/tools/cmd/goimports 16 | go get github.com/golang/lint/golint 17 | go get github.com/smartystreets/goconvey/convey 18 | go get github.com/cactus/go-statsd-client/statsd 19 | go get github.com/rcrowley/go-metrics 20 | go get github.com/DataDog/datadog-go/statsd 21 | 22 | chown -R vagrant:vagrant /go 23 | -------------------------------------------------------------------------------- /examples/metadata/resource/restful_hello.go: -------------------------------------------------------------------------------- 1 | package resource 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | 7 | rf "github.com/go-chassis/go-chassis/v2/server/restful" 8 | ) 9 | 10 | //RestFulHello is a struct used for implementation of restful hello program 11 | type RestFulHello struct { 12 | } 13 | 14 | //Health 15 | func (r *RestFulHello) Health(b *rf.Context) { 16 | b.Write([]byte(fmt.Sprintf("handler chain set metadata %s,set header %s", b.ReadRestfulRequest().Attribute("auth"), b.ReadRequest().Header.Get("X-Auth")))) 17 | } 18 | 19 | //URLPatterns helps to respond for corresponding API calls 20 | func (r *RestFulHello) URLPatterns() []rf.Route { 21 | return []rf.Route{ 22 | {Method: http.MethodGet, Path: "/health", ResourceFunc: r.Health}, 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /configserver/config_server_test.go: -------------------------------------------------------------------------------- 1 | package configserver_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/go-chassis/go-chassis/v2/configserver" 7 | "github.com/go-chassis/go-chassis/v2/core/config" 8 | "github.com/go-chassis/go-chassis/v2/core/config/model" 9 | _ "github.com/go-chassis/go-chassis/v2/core/registry/servicecenter" 10 | _ "github.com/go-chassis/go-chassis/v2/initiator" 11 | "github.com/stretchr/testify/assert" 12 | ) 13 | 14 | func TestGetConfigServerEndpoint(t *testing.T) { 15 | config.GlobalDefinition = &model.GlobalCfg{ 16 | ServiceComb: model.ServiceComb{ 17 | Config: model.Config{ 18 | Client: model.ConfigClient{}, 19 | }, 20 | }, 21 | } 22 | _, err := configserver.GetConfigServerEndpoint() 23 | assert.Error(t, err) 24 | } 25 | -------------------------------------------------------------------------------- /examples/discovery/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/bootstrap" 6 | "github.com/go-chassis/go-chassis/v2/examples/schemas" 7 | _ "github.com/go-chassis/go-chassis/v2/middleware/monitoring" 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}/discovery/server/ 12 | func main() { 13 | chassis.RegisterSchema("rest", &schemas.RestFulHello{}) 14 | chassis.RegisterSchema("rest", &schemas.RestFulMessage{}) 15 | //start all server you register in server/schemas. 16 | if err := chassis.Init(); err != nil { 17 | openlog.Error("Init failed." + err.Error()) 18 | return 19 | } 20 | chassis.Run() 21 | } 22 | -------------------------------------------------------------------------------- /examples/pilot/client/conf/lager.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # LoggerLevel: |DEBUG|INFO|WARN|ERROR|FATAL 3 | logLevel: DEBUG 4 | 5 | # LoggerFile: used to output the name of log.可配置绝对路径,也可以配置用于拼接CHASSIS_HOME的相对路径。 6 | logFile: log/chassis.log 7 | 8 | # LogFormatText:设定日志的输出格式是 json 还是 plaintext (类似于log4j),默认为 false,不建议修改,如果开发过程中想本地查看日志的话, 9 | # 可以设定 LoggerFile 和 LogFormatText 为 true,这样会输出类似于 log4j 格式的本地日志。 10 | logFormatText: true 11 | 12 | #rollingPolicy daily/size;用于配置根据时间,还是根据大小进行日志rotate操作。 13 | rollingPolicy: size 14 | 15 | # MaxDaily of a log file before rotate. By D Days.;日志rotate时间配置,单位"day"。 16 | logRotateAge: 1 17 | 18 | # MaxSize of a log file before rotate. By M Bytes.;日志rotate文件大小配置,单位"MB"。 19 | logRotateSize: 10 20 | 21 | # Max counts to keep of a log's backup files.日志最大存储数量,单位“个”。 22 | logBackupCount: 7 -------------------------------------------------------------------------------- /examples/discovery/client/conf/chassis.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | servicecomb: 3 | registry: 4 | #disabled: false optional:禁用注册发现选项,默认开始注册发现 5 | type: servicecenter #optional:可选zookeeper/servicecenter,zookeeper供中软使用,不配置的情况下默认为servicecenter 6 | scope: full #optional:scope不为full时,只允许在本app间访问,不允许跨app访问;为full就是注册时允许跨app,并且发现本租户全部微服务 7 | address: http://127.0.0.1:30100 8 | #register: manual optional:register不配置时默认为自动注册,可选参数有自动注册auto和手动注册manual 9 | refeshInterval : 30s 10 | watch: true 11 | handler: 12 | chain: 13 | Consumer: 14 | default: bizkeeper-consumer,router,loadbalance,tracing-consumer,transport 15 | transport: 16 | failure: 17 | rest: http_500,http_502 18 | maxIdleCon: 19 | rest: 1024 20 | -------------------------------------------------------------------------------- /examples/discovery/client/conf/lager.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # LoggerLevel: |DEBUG|INFO|WARN|ERROR|FATAL 3 | logLevel: DEBUG 4 | 5 | # LoggerFile: used to output the name of log.可配置绝对路径,也可以配置用于拼接CHASSIS_HOME的相对路径。 6 | logFile: log/chassis.log 7 | 8 | # LogFormatText:设定日志的输出格式是 json 还是 plaintext (类似于log4j),默认为 false,不建议修改,如果开发过程中想本地查看日志的话, 9 | # 可以设定 LoggerFile 和 LogFormatText 为 true,这样会输出类似于 log4j 格式的本地日志。 10 | logFormatText: false 11 | 12 | #rollingPolicy daily/size;用于配置根据时间,还是根据大小进行日志rotate操作。 13 | rollingPolicy: size 14 | 15 | # MaxDaily of a log file before rotate. By D Days.;日志rotate时间配置,单位"day"。 16 | logRotateAge: 1 17 | 18 | # MaxSize of a log file before rotate. By M Bytes.;日志rotate文件大小配置,单位"MB"。 19 | logRotateSize: 10 20 | 21 | # Max counts to keep of a log's backup files.日志最大存储数量,单位“个”。 22 | logBackupCount: 7 -------------------------------------------------------------------------------- /core/provider/provider.go: -------------------------------------------------------------------------------- 1 | package provider 2 | 3 | import ( 4 | "reflect" 5 | 6 | "github.com/go-chassis/go-chassis/v2/core/invocation" 7 | ) 8 | 9 | // Provider is the interface for schema methods 10 | type Provider interface { 11 | //Register a schema 12 | Register(schema interface{}) (string, error) 13 | RegisterName(name string, schema interface{}) error 14 | //invoke schema function 15 | Invoke(inv *invocation.Invocation) (interface{}, error) 16 | GetOperation(schemaID string, operationID string) (Operation, error) 17 | //if exists in local,for localcall 18 | Exist(schemaID, operationID string) bool 19 | } 20 | 21 | // Operation is the interface for schema parameters 22 | type Operation interface { 23 | Method() reflect.Method 24 | Args() []reflect.Type 25 | Reply() []reflect.Type 26 | } 27 | -------------------------------------------------------------------------------- /control/servicecomb/cache.go: -------------------------------------------------------------------------------- 1 | package servicecomb 2 | 3 | import ( 4 | "github.com/go-chassis/go-chassis/v2/control" 5 | "github.com/go-chassis/go-chassis/v2/core/loadbalancer" 6 | "github.com/go-chassis/go-chassis/v2/resilience/retry" 7 | "github.com/patrickmn/go-cache" 8 | ) 9 | 10 | //save configs 11 | var ( 12 | //key is service name 13 | LBConfigCache = cache.New(0, 0) 14 | //key is [Provider|Consumer]:service_name or [Consumer|Provider] 15 | CBConfigCache = cache.New(0, 0) 16 | RLConfigCache = cache.New(0, 0) 17 | EgressConfigCache = cache.New(0, 0) 18 | FIConfigCache = cache.New(0, 0) 19 | ) 20 | 21 | //Default values 22 | var ( 23 | DefaultLB = control.LoadBalancingConfig{ 24 | Strategy: loadbalancer.StrategyRoundRobin, 25 | BackOffKind: retry.DefaultBackOffKind, 26 | } 27 | ) 28 | -------------------------------------------------------------------------------- /examples/metadata/resource/handler.go: -------------------------------------------------------------------------------- 1 | package resource 2 | 3 | import ( 4 | "github.com/go-chassis/go-chassis/v2/core/handler" 5 | "github.com/go-chassis/go-chassis/v2/core/invocation" 6 | ) 7 | 8 | //MetadataHandler 9 | type MetadataHandler struct { 10 | } 11 | 12 | //Handle 13 | func (h *MetadataHandler) Handle(chain *handler.Chain, inv *invocation.Invocation, cb invocation.ResponseCallBack) { 14 | inv.SetMetadata("auth", "user1") 15 | inv.SetHeader("X-Auth", "user2") 16 | chain.Next(inv, cb) 17 | } 18 | 19 | //Name 20 | func (h *MetadataHandler) Name() string { 21 | return "test" 22 | } 23 | func newMetadataHandler() handler.Handler { 24 | //call next chain 25 | 26 | return &MetadataHandler{} 27 | } 28 | 29 | func init() { 30 | handler.RegisterHandler("metadata-handler", newMetadataHandler) 31 | } 32 | -------------------------------------------------------------------------------- /control/strcut.go: -------------------------------------------------------------------------------- 1 | package control 2 | 3 | //LoadBalancingConfig is a standardized model 4 | type LoadBalancingConfig struct { 5 | Strategy string 6 | Filters []string 7 | RetryEnabled bool 8 | RetryOnSame int 9 | RetryOnNext int 10 | BackOffKind string 11 | BackOffMin int 12 | BackOffMax int 13 | 14 | SessionTimeoutInSeconds int 15 | SuccessiveFailedTimes int 16 | } 17 | 18 | //RateLimitingConfig is a standardized model 19 | type RateLimitingConfig struct { 20 | Key string 21 | Enabled bool 22 | Rate int 23 | } 24 | 25 | //EgressConfig is a standardized model 26 | type EgressConfig struct { 27 | Hosts []string 28 | Ports []*EgressPort 29 | } 30 | 31 | //EgressPort protocol and the corresponding port 32 | type EgressPort struct { 33 | Port int32 34 | Protocol string 35 | } 36 | -------------------------------------------------------------------------------- /core/registry/servicecenter/util_test.go: -------------------------------------------------------------------------------- 1 | package servicecenter_test 2 | 3 | import ( 4 | "github.com/go-chassis/go-chassis/v2/core/registry" 5 | "github.com/go-chassis/go-chassis/v2/core/registry/servicecenter" 6 | "github.com/patrickmn/go-cache" 7 | "github.com/stretchr/testify/assert" 8 | "testing" 9 | ) 10 | 11 | func TestGetCriteria(t *testing.T) { 12 | registry.ProvidersMicroServiceCache = cache.New(0, 0) 13 | registry.AddProviderToCache("service1", "1") 14 | registry.AddProviderToCache("service1", "2") 15 | registry.AddProviderToCache("service2", "2") 16 | c := servicecenter.GetCriteria() 17 | assert.Equal(t, 3, len(c)) 18 | c = servicecenter.GetCriteriaByService("service1") 19 | assert.Equal(t, 2, len(c)) 20 | c = servicecenter.GetCriteriaByService("service2") 21 | assert.Equal(t, 1, len(c)) 22 | } 23 | -------------------------------------------------------------------------------- /client/rest/restful.go: -------------------------------------------------------------------------------- 1 | package rest 2 | 3 | import ( 4 | "bytes" 5 | "github.com/go-chassis/go-chassis/v2/core/client" 6 | "io" 7 | "net/http" 8 | ) 9 | 10 | //NewRequest is a function which creates new request 11 | func NewRequest(method, urlStr string, body []byte) (*http.Request, error) { 12 | var r io.Reader 13 | if body != nil { 14 | r = bytes.NewReader(body) 15 | } 16 | 17 | req, err := http.NewRequest(method, urlStr, r) 18 | if err != nil { 19 | return nil, err 20 | } 21 | return req, nil 22 | } 23 | 24 | // NewResponse is creating the object of response 25 | func NewResponse() *http.Response { 26 | resp := &http.Response{ 27 | Header: http.Header{}, 28 | } 29 | return resp 30 | } 31 | 32 | //Client is a struct 33 | type Client struct { 34 | c *http.Client 35 | opts client.Options 36 | } 37 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | .. go-chassis documentation master file, created by 2 | sphinx-quickstart on Fri Apr 13 17:13:49 2018. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to go-chassis's documentation! 7 | ====================================== 8 | .. toctree:: 9 | :maxdepth: 4 10 | :caption: User Documentations 11 | :glob: 12 | 13 | intro 14 | get-started 15 | user-guides 16 | middleware 17 | control-plane 18 | plugin-tracing-guides 19 | protocol-plugins 20 | 21 | .. toctree:: 22 | :maxdepth: 2 23 | :caption: Development Documentations 24 | 25 | dev-guides 26 | 27 | .. toctree:: 28 | :maxdepth: 2 29 | :caption: Design Documentations 30 | 31 | design-guides 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /examples/metadata/conf/lager.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | logWriters: file,stdout 3 | # LoggerLevel: |DEBUG|INFO|WARN|ERROR|FATAL 4 | logLevel: DEBUG 5 | 6 | # LoggerFile: used to output the name of log.可配置绝对路径,也可以配置用于拼接CHASSIS_HOME的相对路径。 7 | logFile: log/chassis.log 8 | 9 | # LogFormatText:设定日志的输出格式是 json 还是 plaintext (类似于log4j),默认为 false,不建议修改,如果开发过程中想本地查看日志的话, 10 | # 可以设定 LoggerFile 和 LogFormatText 为 true,这样会输出类似于 log4j 格式的本地日志。 11 | logFormatText: true 12 | 13 | #rollingPolicy daily/size;用于配置根据时间,还是根据大小进行日志rotate操作。 14 | rollingPolicy: size 15 | 16 | # MaxDaily of a log file before rotate. By D Days.;日志rotate时间配置,单位"day"。 17 | logRotateAge: 1 18 | 19 | # MaxSize of a log file before rotate. By M Bytes.;日志rotate文件大小配置,单位"MB"。 20 | logRotateSize: 10 21 | 22 | # Max counts to keep of a log's backup files.日志最大存储数量,单位“个”。 23 | logBackupCount: 7 -------------------------------------------------------------------------------- /examples/pilot/server/conf/lager.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | logWriters: file,stdout 3 | # LoggerLevel: |DEBUG|INFO|WARN|ERROR|FATAL 4 | logLevel: DEBUG 5 | 6 | # LoggerFile: used to output the name of log.可配置绝对路径,也可以配置用于拼接CHASSIS_HOME的相对路径。 7 | logFile: log/chassis.log 8 | 9 | # LogFormatText:设定日志的输出格式是 json 还是 plaintext (类似于log4j),默认为 false,不建议修改,如果开发过程中想本地查看日志的话, 10 | # 可以设定 LoggerFile 和 LogFormatText 为 true,这样会输出类似于 log4j 格式的本地日志。 11 | logFormatText: true 12 | 13 | #rollingPolicy daily/size;用于配置根据时间,还是根据大小进行日志rotate操作。 14 | rollingPolicy: size 15 | 16 | # MaxDaily of a log file before rotate. By D Days.;日志rotate时间配置,单位"day"。 17 | logRotateAge: 1 18 | 19 | # MaxSize of a log file before rotate. By M Bytes.;日志rotate文件大小配置,单位"MB"。 20 | logRotateSize: 10 21 | 22 | # Max counts to keep of a log's backup files.日志最大存储数量,单位“个”。 23 | logBackupCount: 7 -------------------------------------------------------------------------------- /scripts/version_set.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | 5 | CURRENT_DIR=$(cd $(dirname $0);pwd) 6 | CHASSIS_DIR=$(dirname $CURRENT_DIR) 7 | 8 | FRAMEWORK_FILE="$CHASSIS_DIR/core/metadata/framework.go" 9 | 10 | if [ ! -f "$FRAMEWORK_FILE" ]; then 11 | echo "$FRAMEWORK_FILE not exist!" 12 | exit 1 13 | fi 14 | 15 | version=${1:-"0.1"} 16 | cat << EOF > $FRAMEWORK_FILE 17 | // Code generated by go-chassis/scripts/version_set.sh. DO NOT EDIT. 18 | 19 | // Package metadata provides framework info registered to registry. 20 | package metadata 21 | 22 | // constant for sdk version, name, registration component 23 | const ( 24 | SdkVersion = "$version" 25 | SdkName = "Go-Chassis" 26 | SdkRegistrationComponent = "SDK" 27 | PlatformRegistrationComponent = "PLATFORM" 28 | ) 29 | EOF 30 | -------------------------------------------------------------------------------- /core/loadbalancer/strategy.go: -------------------------------------------------------------------------------- 1 | package loadbalancer 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "time" 7 | 8 | "github.com/go-chassis/openlog" 9 | ) 10 | 11 | var strategies = make(map[string]func() Strategy) 12 | var i int 13 | 14 | func init() { 15 | rand.Seed(time.Now().UnixNano()) 16 | rand.Seed(time.Now().Unix()) 17 | i = rand.Int() 18 | } 19 | 20 | // InstallStrategy install strategy 21 | func InstallStrategy(name string, s func() Strategy) { 22 | strategies[name] = s 23 | openlog.Debug(fmt.Sprintf("installed strategy plugin: %s.", name)) 24 | } 25 | 26 | // GetStrategyPlugin get strategy plugin 27 | func GetStrategyPlugin(name string) (func() Strategy, error) { 28 | s, ok := strategies[name] 29 | if !ok { 30 | return nil, fmt.Errorf("don't support strategyName [%s]", name) 31 | } 32 | 33 | return s, nil 34 | } 35 | -------------------------------------------------------------------------------- /control/servicecomb/qps_event_listener_test.go: -------------------------------------------------------------------------------- 1 | package servicecomb_test 2 | 3 | import ( 4 | "github.com/go-chassis/go-archaius/event" 5 | "github.com/go-chassis/go-chassis/v2/control/servicecomb" 6 | "testing" 7 | ) 8 | 9 | func TestQpsEvent(t *testing.T) { 10 | servicecomb.Init() 11 | eventListen := &servicecomb.QPSEventListener{} 12 | t.Log("sending the events for the key cse.flowcontrol.Consumer.qps.limit.Server") 13 | e := &event.Event{EventType: "UPDATE", Key: "cse.flowcontrol.Consumer.qps.limit.Server", Value: 199} 14 | eventListen.Event(e) 15 | 16 | e1 := &event.Event{EventType: "CREATE", Key: "cse.flowcontrol.Provider.qps.limit.Server", Value: 100} 17 | eventListen.Event(e1) 18 | 19 | e2 := &event.Event{EventType: "DELETE", Key: "cse.flowcontrol.Consumer.qps.limit.Server", Value: 199} 20 | eventListen.Event(e2) 21 | 22 | } 23 | -------------------------------------------------------------------------------- /licenses/LICENSE_davecgh_go-spew: -------------------------------------------------------------------------------- 1 | ISC License 2 | 3 | Copyright (c) 2012-2016 Dave Collins 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any 6 | purpose with or without fee is hereby granted, provided that the above 7 | copyright notice and this permission notice appear in all copies. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | -------------------------------------------------------------------------------- /examples/marker/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 | _ "github.com/go-chassis/go-chassis/v2/middleware/ratelimiter" 10 | ) 11 | 12 | type Hello struct{} 13 | 14 | //Hello 15 | func (r *Hello) Hello(b *rf.Context) { b.Write([]byte("hi from hello")) } 16 | 17 | //URLPatterns helps to respond for corresponding API calls 18 | func (r *Hello) URLPatterns() []rf.Route { 19 | return []rf.Route{ 20 | {Method: http.MethodGet, Path: "/hello", ResourceFunc: r.Hello}, 21 | } 22 | } 23 | 24 | func main() { 25 | chassis.RegisterSchema("rest", &Hello{}) 26 | if err := chassis.Init(); err != nil { 27 | openlog.Fatal("Init failed." + err.Error()) 28 | return 29 | } 30 | chassis.Run() 31 | } 32 | -------------------------------------------------------------------------------- /core/fault/fault_injection_test.go: -------------------------------------------------------------------------------- 1 | package fault_test 2 | 3 | import ( 4 | "fmt" 5 | "github.com/go-chassis/go-chassis/v2/core/config/model" 6 | "github.com/go-chassis/go-chassis/v2/core/fault" 7 | "github.com/go-chassis/go-chassis/v2/core/invocation" 8 | "github.com/stretchr/testify/assert" 9 | "testing" 10 | "time" 11 | ) 12 | 13 | func Test_ApplyFaultInjection(t *testing.T) { 14 | var inv = new(invocation.Invocation) 15 | var fault1 = new(model.Fault) 16 | inv.Endpoint = "1.2.3.4" 17 | inv.MicroServiceName = "Server" 18 | fault1.Delay.FixedDelay = 2 * time.Second 19 | //delay must not return error 20 | v := fault.ApplyFaultInjection(fault1, inv, 100, "delay") 21 | assert.Equal(t, v, nil) 22 | //abort must return error 23 | v = fault.ApplyFaultInjection(fault1, inv, 100, "abort") 24 | assert.Equal(t, v, fmt.Errorf("injecting abort")) 25 | } 26 | -------------------------------------------------------------------------------- /examples/pilot/server/conf/tls.yaml: -------------------------------------------------------------------------------- 1 | # ssl: 2 | # registry.Consumer.cipherPlugin: default 3 | # registry.Consumer.verifyPeer: false 4 | # registry.Consumer.cipherSuits: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 5 | # registry.Consumer.protocol: TLSv1.2 6 | # registry.Consumer.caFile: 7 | # registry.Consumer.certFile: 8 | # registry.Consumer.keyFile: 9 | # registry.Consumer.certPwdFile: 10 | 11 | # configServer.Consumer.cipherPlugin: default 12 | # configServer.Consumer.verifyPeer: false 13 | # configServer.Consumer.cipherSuits: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 14 | # configServer.Consumer.protocol: TLSv1.2 15 | # configServer.Consumer.caFile: 16 | # configServer.Consumer.certFile: 17 | # configServer.Consumer.keyFile: 18 | # configServer.Consumer.certPwdFile: 19 | -------------------------------------------------------------------------------- /examples/discovery/server/conf/tls.yaml: -------------------------------------------------------------------------------- 1 | # ssl: 2 | # registry.Consumer.cipherPlugin: default 3 | # registry.Consumer.verifyPeer: false 4 | # registry.Consumer.cipherSuits: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 5 | # registry.Consumer.protocol: TLSv1.2 6 | # registry.Consumer.caFile: 7 | # registry.Consumer.certFile: 8 | # registry.Consumer.keyFile: 9 | # registry.Consumer.certPwdFile: 10 | 11 | # configServer.Consumer.cipherPlugin: default 12 | # configServer.Consumer.verifyPeer: false 13 | # configServer.Consumer.cipherSuits: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 14 | # configServer.Consumer.protocol: TLSv1.2 15 | # configServer.Consumer.caFile: 16 | # configServer.Consumer.certFile: 17 | # configServer.Consumer.keyFile: 18 | # configServer.Consumer.certPwdFile: 19 | -------------------------------------------------------------------------------- /core/loadbalancer/struct.go: -------------------------------------------------------------------------------- 1 | package loadbalancer 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | // ProtocolStats store protocol stats 8 | type ProtocolStats struct { 9 | Latency []time.Duration 10 | Addr string 11 | AvgLatency time.Duration 12 | } 13 | 14 | // CalculateAverageLatency make avg latency 15 | func (ps *ProtocolStats) CalculateAverageLatency() { 16 | var sum time.Duration 17 | for i := 0; i < len(ps.Latency); i++ { 18 | sum = sum + ps.Latency[i] 19 | } 20 | if len(ps.Latency) == 0 { 21 | return 22 | } 23 | ps.AvgLatency = time.Duration(sum.Nanoseconds() / int64(len(ps.Latency))) 24 | } 25 | 26 | // SaveLatency save latest 10 record 27 | func (ps *ProtocolStats) SaveLatency(l time.Duration) { 28 | if len(ps.Latency) >= 10 { 29 | //save latest 10 latencies 30 | ps.Latency = ps.Latency[1:] 31 | } 32 | ps.Latency = append(ps.Latency, l) 33 | } 34 | -------------------------------------------------------------------------------- /core/config/cd_config.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import "github.com/go-chassis/go-archaius" 4 | 5 | // GetContractDiscoveryType returns the Type of contract discovery registry 6 | func GetContractDiscoveryType() string { 7 | return GlobalDefinition.ServiceComb.Registry.Type 8 | } 9 | 10 | // GetContractDiscoveryAddress returns the Address of contract discovery registry 11 | func GetContractDiscoveryAddress() string { 12 | return GlobalDefinition.ServiceComb.Registry.Address 13 | } 14 | 15 | // GetContractDiscoveryAPIVersion returns the APIVersion of contract discovery registry 16 | func GetContractDiscoveryAPIVersion() string { 17 | return GlobalDefinition.ServiceComb.Registry.APIVersion.Version 18 | } 19 | 20 | // GetContractDiscoveryDisable returns the Disable of contract discovery registry 21 | func GetContractDiscoveryDisable() bool { 22 | return archaius.GetBool("servicecomb.registry.disabled", false) 23 | } 24 | -------------------------------------------------------------------------------- /docs/control-plane/cse.md: -------------------------------------------------------------------------------- 1 | # ServiceStage 2 | ServiceStage 是华为云推出的云服务,通过其中的CSE(cloud service engine)子服务,你可以快速启动ServiceComb service center服务,配置中心或是其他面向云原生开发的服务。每个服务集群被称为engine。 3 | 4 | ## 如何使用 5 | ### 通过配置文件配置AK SK 6 | 1.在auth.yaml文件中进行配置 7 | 8 | ```yaml 9 | ## Huawei Public Cloud ak/sk 10 | servicecomb: 11 | credentials: 12 | accessKey: xxx 13 | secretKey: xxx 14 | ``` 15 | 16 | 完整的[example](https://github.com/go-chassis/go-chassis-examples/tree/master/huaweicse) 17 | ### 通过使用ServiceStage部署,免AKSK配置 18 | 使用ServiceStage进行部署的微服务无需进行ak sk手工配置,框架自动发现service center等服务的地址 19 | 1.必须在main.go中import 华为的扩展组件用于自动查询服务的endpoint 20 | 21 | ```go 22 | import _ "github.com/go-chassis/go-chassis-cloud/provider/huawei/engine" 23 | ``` 24 | 2.在chassis.yaml中设置引擎名字 25 | ```yaml 26 | servicecomb: 27 | engine: 28 | name: test-engine 29 | ``` 30 | 完整的[example](https://github.com/go-chassis/go-chassis-cloud/tree/master/example) 31 | -------------------------------------------------------------------------------- /examples/discovery/client/conf/circuit_breaker.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | cse: 3 | isolation: 4 | Consumer: 5 | timeoutInMilliseconds: 1000 6 | maxConcurrentRequests: 100 7 | Server: 8 | timeoutInMilliseconds: 1000 9 | maxConcurrentRequests: 1 10 | circuitBreaker: 11 | Consumer: 12 | enabled: false 13 | forceOpen: false 14 | forceClosed: false 15 | sleepWindowInMilliseconds: 10000 16 | requestVolumeThreshold: 20 17 | errorThresholdPercentage: 10 18 | Server: 19 | enabled: true 20 | forceOpen: false 21 | forceClosed: false 22 | sleepWindowInMilliseconds: 10000 23 | requestVolumeThreshold: 20 24 | errorThresholdPercentage: 50 25 | #容错处理函数,目前暂时按照开源的方式来不进行区分处理,统一调用fallback函数 26 | fallback: 27 | Consumer: 28 | enabled: true 29 | fallbackpolicy: 30 | Consumer: 31 | policy: throwexception -------------------------------------------------------------------------------- /pkg/profile/profile_test.go: -------------------------------------------------------------------------------- 1 | package profile 2 | 3 | import ( 4 | "github.com/go-chassis/go-chassis/v2/core/config" 5 | "github.com/go-chassis/go-chassis/v2/core/registry" 6 | "github.com/go-chassis/go-chassis/v2/core/router" 7 | _ "github.com/go-chassis/go-chassis/v2/core/router/servicecomb" 8 | "github.com/stretchr/testify/assert" 9 | "testing" 10 | ) 11 | 12 | func TestProfile(t *testing.T) { 13 | err := router.BuildRouter("cse") 14 | assert.NoError(t, err) 15 | rr := map[string][]*config.RouteRule{"test": {{Precedence: 10}}} 16 | router.DefaultRouter.SetRouteRule(rr) 17 | 18 | registry.MicroserviceInstanceIndex = registry.NewIndexCache() 19 | registry.MicroserviceInstanceIndex.Set("test", []*registry.MicroServiceInstance{{InstanceID: "id"}}) 20 | 21 | p := newProfile() 22 | 23 | assert.Equal(t, 10, p.RouteRule["test"][0].Precedence) 24 | assert.Equal(t, "id", p.Discovery["test"][0].InstanceID) 25 | } 26 | -------------------------------------------------------------------------------- /docs/middleware/access-log.md: -------------------------------------------------------------------------------- 1 | # access log 2 | record access log as a handler in provider chain 3 | ## usage 4 | 5 | 1.add this in provider chain, and as the first handler 6 | ```yaml 7 | servicecomb: 8 | registry: 9 | disabled: true 10 | registry: manual 11 | protocols: # what kind of server you want to launch 12 | rest: #launch a http server 13 | listenAddress: 127.0.0.1:5001 14 | handler: 15 | chain: 16 | Provider: 17 | default: access-log 18 | ``` 19 | 2.add a config in lager.yaml 20 | ```yaml 21 | # can be a file path or stdout 22 | # a file path: record access log in this file, recommend access file path' dir is same as log file'dir 23 | # stdout: access log will record in console stdout 24 | accessLogFile: xxx 25 | ``` 26 | 27 | 3.import access log package 28 | ```go 29 | // should import after import go-chassis 30 | _ "github.com/go-chassis/go-chassis/v2/middleware/accesslog" 31 | ``` 32 | -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=. 11 | set BUILDDIR=_build 12 | set SPHINXPROJ=go-chassis 13 | 14 | if "%1" == "" goto help 15 | 16 | %SPHINXBUILD% >NUL 2>NUL 17 | if errorlevel 9009 ( 18 | echo. 19 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 20 | echo.installed, then set the SPHINXBUILD environment variable to point 21 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 22 | echo.may add the Sphinx directory to PATH. 23 | echo. 24 | echo.If you don't have Sphinx installed, grab it from 25 | echo.http://sphinx-doc.org/ 26 | exit /b 1 27 | ) 28 | 29 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 30 | goto end 31 | 32 | :help 33 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 34 | 35 | :end 36 | popd 37 | -------------------------------------------------------------------------------- /licenses/NOTICE_prometheus_client_golang: -------------------------------------------------------------------------------- 1 | Prometheus instrumentation library for Go applications 2 | Copyright 2012-2015 The Prometheus Authors 3 | 4 | This product includes software developed at 5 | SoundCloud Ltd. (http://soundcloud.com/). 6 | 7 | 8 | The following components are included in this product: 9 | 10 | perks - a fork of https://github.com/bmizerany/perks 11 | https://github.com/beorn7/perks 12 | Copyright 2013-2015 Blake Mizerany, Björn Rabenstein 13 | See https://github.com/beorn7/perks/blob/master/README.md for license details. 14 | 15 | Go support for Protocol Buffers - Google's data interchange format 16 | http://github.com/golang/protobuf/ 17 | Copyright 2010 The Go Authors 18 | See source code for license details. 19 | 20 | Support for streaming Protocol Buffer messages for the Go language (golang). 21 | https://github.com/matttproud/golang_protobuf_extensions 22 | Copyright 2013 Matt T. Proud 23 | Licensed under the Apache License, Version 2.0 24 | -------------------------------------------------------------------------------- /docs/user-guides/log.md: -------------------------------------------------------------------------------- 1 | # Log 2 | ## 概述 3 | 4 | 用户可配置微服务的运行日志的相关属性,比如输出方式,日志级别,文件路径以及日志转储相关属性。 5 | 6 | ## 配置 7 | 8 | 日志配置文件为lager.yaml,配置模板如下: 9 | 10 | - logLevel: 由低到高分别为 DEBUG, INFO, WARN, ERROR, FATAL 共5个级别,这里设置的级别是日志输出的最低级别,只有不低于该级别的日志才会输出。 11 | - logWriters: 表示日志的输出方式,默认为文件和标准输出。 12 | - logFile: 日志路径 13 | - logFormatText: 默认为false,即设定日志的输出格式为 json。若为true则输出格式为plaintext,类似log4j。建议使用json格式输出的日志。 14 | - logRotateDisable: 是否开启日志绕接. 15 | - logRotateCompress: 是否压缩旧的日志 16 | - logRotateAge: 日志rotate时间配置,单位"day",范围为(0, 10)。 17 | - logRotateSize: 日志rotate文件大小配置,单位"MB",范围为(0,50)。 18 | - logBackupCount: 日志最大存储数量,单位“个”,范围为[0,100)。 19 | 20 | ```yaml 21 | --- 22 | logWriters: file,stdout 23 | # LoggerLevel: |DEBUG|INFO|WARN|ERROR|FATAL 24 | logLevel: DEBUG 25 | logFile: log/chassis.log 26 | logFormatText: false 27 | logRotateDisable: false 28 | #log rotate and backup settings 29 | logRotateAge: 1 # after n days 30 | logRotateSize: 10 # megabytes 31 | logBackupCount: 7 32 | ``` 33 | -------------------------------------------------------------------------------- /core/fault/fault.go: -------------------------------------------------------------------------------- 1 | package fault 2 | 3 | import ( 4 | "github.com/go-chassis/go-chassis/v2/core/config/model" 5 | "github.com/go-chassis/go-chassis/v2/core/invocation" 6 | ) 7 | 8 | // InjectFault inject fault 9 | type InjectFault func(model.Fault, *invocation.Invocation) error 10 | 11 | // Injectors fault injectors 12 | var Injectors = make(map[string]InjectFault) 13 | 14 | //Fault fault injection error 15 | type Fault struct { 16 | Message string 17 | } 18 | 19 | func (e Fault) Error() string { 20 | return e.Message 21 | } 22 | 23 | // InstallFaultInjectionPlugin install fault injection plugin 24 | func InstallFaultInjectionPlugin(name string, f InjectFault) { 25 | Injectors[name] = f 26 | } 27 | 28 | func init() { 29 | InstallFaultInjectionPlugin("rest", faultInject) 30 | InstallFaultInjectionPlugin("dubbo", faultInject) 31 | } 32 | 33 | func faultInject(rule model.Fault, inv *invocation.Invocation) error { 34 | return ValidateAndApplyFault(&rule, inv) 35 | } 36 | -------------------------------------------------------------------------------- /examples/pilot/client/conf/chassis.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | servicecomb: 3 | registry: 4 | type: pilot 5 | # refreshInterval: 30s 6 | address: http://istio-pilot.istio-system:8080 7 | protocols: 8 | rest: 9 | listenAddress: 127.0.0.1:8085 10 | advertiseAddress: 127.0.0.1:8085 11 | failure: http_500,http_502 # Defines what is considered an unsuccessful attempt of communication with a server. 12 | handler: 13 | chain: 14 | Consumer: 15 | default: bizkeeper-consumer, router, loadbalance, ratelimiter-consumer,transport 16 | # ssl: 17 | # registry.Consumer.cipherPlugin: default 18 | # registry.Consumer.verifyPeer: false 19 | # registry.Consumer.cipherSuits: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 20 | # registry.Consumer.protocol: TLSv1.2 21 | # registry.Consumer.caFile: 22 | # registry.Consumer.certFile: 23 | # registry.Consumer.keyFile: 24 | # registry.Consumer.certPwdFile: 25 | -------------------------------------------------------------------------------- /server/restful/common.go: -------------------------------------------------------------------------------- 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 restful 19 | 20 | //HeaderAuth is const 21 | const HeaderAuth = "Authorization" 22 | -------------------------------------------------------------------------------- /docs/middleware/rate-limiting.md: -------------------------------------------------------------------------------- 1 | # Rate limiting v1 2 | ## 概述 3 | 4 | 用户可以通过配置限流策略限制provider端的请求频率,使每秒请求数限制在最大请求量的大小。配置可限制接收处理请求的频率 5 | 6 | ## 配置 7 | 8 | 限流配置在rate_limiting.yaml中,同时需要在chassis.yaml的handler chain中添加handler。 9 | 10 | **cse.flowcontrol.Provider.qps.enabled** 11 | > *(optional, bool)* 是否开启限流,默认true 12 | 13 | **cse.flowcontrol.Provider.qps.global.limit** 14 | > *(optional, int)* 每秒允许的请求数,默认2147483647max int) 15 | 16 | 引入middleware 17 | ```go 18 | import _ github.com/go-chassis/go-chassis/v2/middleware/ratelimiter 19 | ``` 20 | #### Provider示例 21 | 22 | provider端需要在chassis.yaml添加ratelimiter-provider。同时在rate\_limiting.yaml中配置具体的请求数。 23 | 24 | ```yaml 25 | servicecomb: 26 | handler: 27 | chain: 28 | Provider: 29 | default: ratelimiter-provider 30 | ``` 31 | 32 | ```yaml 33 | cse: 34 | flowcontrol: 35 | Provider: 36 | qps: 37 | enabled: true # enable rate limiting or not 38 | global: 39 | limit: 100 40 | ``` 41 | -------------------------------------------------------------------------------- /control/servicecomb/loadbalance_event_listener.go: -------------------------------------------------------------------------------- 1 | package servicecomb 2 | 3 | import ( 4 | "fmt" 5 | "github.com/go-chassis/go-archaius/event" 6 | "github.com/go-chassis/go-chassis/v2/core/config" 7 | "github.com/go-chassis/openlog" 8 | ) 9 | 10 | // constants for loadbalancer strategy name, and timeout 11 | const ( 12 | //LoadBalanceKey is variable of type string that matches load balancing events 13 | LoadBalanceKey = "^cse\\.loadbalance\\." 14 | ) 15 | 16 | //LoadBalancingEventListener is a struct 17 | type LoadBalancingEventListener struct { 18 | Key string 19 | } 20 | 21 | //Event is a method used to handle a load balancing event 22 | func (e *LoadBalancingEventListener) Event(evt *event.Event) { 23 | openlog.Debug(fmt.Sprintf("LB event, key: %s, type: %s", evt.Key, evt.EventType)) 24 | if err := config.ReadLBFromArchaius(); err != nil { 25 | openlog.Error("can not unmarshal new lb config: " + err.Error()) 26 | } 27 | SaveToLBCache(config.GetLoadBalancing()) 28 | } 29 | -------------------------------------------------------------------------------- /core/config/archaius_test.go: -------------------------------------------------------------------------------- 1 | package config_test 2 | 3 | import ( 4 | "os" 5 | "path/filepath" 6 | "testing" 7 | ) 8 | 9 | func TestMain(m *testing.M) { 10 | lbBytes := []byte(` 11 | cse: 12 | loadbalance: 13 | TargetService: 14 | backoff: 15 | maxMs: 400 16 | minMs: 200 17 | kind: constant 18 | retryEnabled: false 19 | retryOnNext: 2 20 | retryOnSame: 3 21 | serverListFilters: zoneaware 22 | strategy: 23 | name: WeightedResponse 24 | backoff: 25 | maxMs: 400 26 | minMs: 200 27 | kind: constant 28 | retryEnabled: false 29 | retryOnNext: 2 30 | retryOnSame: 3 31 | serverListFilters: zoneaware 32 | strategy: 33 | name: WeightedResponse 34 | 35 | `) 36 | d, _ := os.Getwd() 37 | filename3 := filepath.Join(d, "load_balancing.yaml") 38 | f3, _ := os.OpenFile(filename3, os.O_RDWR|os.O_TRUNC|os.O_CREATE, 0666) 39 | _, _ = f3.Write(lbBytes) 40 | m.Run() 41 | } 42 | -------------------------------------------------------------------------------- /core/loadbalancer/randam.go: -------------------------------------------------------------------------------- 1 | package loadbalancer 2 | 3 | import ( 4 | "github.com/go-chassis/go-chassis/v2/core/invocation" 5 | "github.com/go-chassis/go-chassis/v2/core/registry" 6 | 7 | "math/rand" 8 | "sync" 9 | ) 10 | 11 | // RandomStrategy is strategy 12 | type RandomStrategy struct { 13 | instances []*registry.MicroServiceInstance 14 | mtx sync.Mutex 15 | } 16 | 17 | func newRandomStrategy() Strategy { 18 | return &RandomStrategy{} 19 | } 20 | 21 | // ReceiveData receive data 22 | func (r *RandomStrategy) ReceiveData(inv *invocation.Invocation, instances []*registry.MicroServiceInstance, serviceName string) { 23 | r.instances = instances 24 | } 25 | 26 | // Pick return instance 27 | func (r *RandomStrategy) Pick() (*registry.MicroServiceInstance, error) { 28 | if len(r.instances) == 0 { 29 | return nil, ErrNoneAvailableInstance 30 | } 31 | 32 | r.mtx.Lock() 33 | k := rand.Int() % len(r.instances) 34 | r.mtx.Unlock() 35 | return r.instances[k], nil 36 | 37 | } 38 | -------------------------------------------------------------------------------- /control/servicecomb/event_register.go: -------------------------------------------------------------------------------- 1 | package servicecomb 2 | 3 | import ( 4 | "github.com/go-chassis/go-archaius" 5 | "github.com/go-chassis/go-archaius/event" 6 | "github.com/go-chassis/openlog" 7 | ) 8 | 9 | //RegisterKeys registers a config key to the archaius 10 | func RegisterKeys(eventListener event.Listener, keys ...string) { 11 | err := archaius.RegisterListener(eventListener, keys...) 12 | if err != nil { 13 | openlog.Error(err.Error()) 14 | } 15 | } 16 | 17 | //Init is a function 18 | func Init() { 19 | qpsEventListener := &QPSEventListener{} 20 | circuitBreakerEventListener := &CircuitBreakerEventListener{} 21 | lbEventListener := &LoadBalancingEventListener{} 22 | 23 | RegisterKeys(qpsEventListener, Prefix) 24 | RegisterKeys(circuitBreakerEventListener, ConsumerFallbackKey, ConsumerFallbackPolicyKey, ConsumerIsolationKey, ConsumerCircuitBreakerKey) 25 | RegisterKeys(lbEventListener, LoadBalanceKey) 26 | RegisterKeys(&LagerEventListener{}, LagerLevelKey) 27 | 28 | } 29 | -------------------------------------------------------------------------------- /docs/getstarted/install.md: -------------------------------------------------------------------------------- 1 | Minimize Installation 2 | ===== 3 | 1.Install [go 1.13+](https://golang.org/doc/install) 4 | 5 | 2.Generate go mod 6 | ```bash 7 | go mod init 8 | ``` 9 | 3.Add go chassis 10 | ```bash 11 | go get github.com/go-chassis/go-chassis/v2@v2.0.2 12 | ``` 13 | 14 | 4.Use go mod 15 | ```bash 16 | GO111MODULE=on go mod download 17 | #optional 18 | GO111MODULE=on go mod vendor 19 | ``` 20 | 21 | if you are facing network issue 22 | ```bash 23 | export GOPROXY=https://goproxy.io 24 | ``` 25 | 5.Install [service-center](https://service-center.readthedocs.io/en/latest/get-started/install.html) 26 | 27 | 6.[Write your first http micro service](https://go-chassis.readthedocs.io/en/latest/getstarted/writing-rest.html) 28 | 29 | 30 | Use gRPC communication 31 | =================== 32 | follow https://developers.google.com/protocol-buffers/docs/gotutorial to install grpc 33 | 34 | [Write your first grpc micro service](https://go-chassis.readthedocs.io//getstarted/writing-rpc.html) 35 | -------------------------------------------------------------------------------- /pkg/goplugin/plugin.go: -------------------------------------------------------------------------------- 1 | package goplugin 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/go-chassis/go-chassis/v2/pkg/util/fileutil" 7 | ) 8 | 9 | // LookupPlugin lookup plugin 10 | // Caller needs to determine itself whether the plugin file exists 11 | func LookupPlugin(name string) (string, error) { 12 | var pluginPath string 13 | var err error 14 | // firstly search plugin in {ChassisHome}/lib 15 | pluginPath = fileutil.ChassisHomeDir() + "/lib/" + name 16 | if _, err = os.Stat(pluginPath); err == nil { 17 | return pluginPath, nil 18 | } 19 | if !os.IsNotExist(err) { 20 | return "", err 21 | } 22 | 23 | // secondly search plugin in /usr/lib 24 | pluginPath = "/usr/lib/" + name 25 | if _, err = os.Stat(pluginPath); err == nil { 26 | return pluginPath, nil 27 | } 28 | return "", err 29 | } 30 | 31 | // LookUpSymbolFromPlugin looks up symbol from the plugin 32 | func LookUpSymbolFromPlugin(plugName, symName string) (interface{}, error) { 33 | return lookUp(plugName, symName) 34 | } 35 | -------------------------------------------------------------------------------- /third_party/forked/afex/hystrix-go/hystrix/pool.go: -------------------------------------------------------------------------------- 1 | package hystrix 2 | 3 | type executorPool struct { 4 | Name string 5 | Metrics *poolMetrics 6 | Max int 7 | Tickets chan *struct{} 8 | } 9 | 10 | const ConcurrentRequestsLimit = 5000 11 | 12 | func newExecutorPool(name string) *executorPool { 13 | p := &executorPool{} 14 | p.Name = name 15 | p.Metrics = newPoolMetrics(name) 16 | p.Max = getSettings(name).MaxConcurrentRequests 17 | if p.Max > ConcurrentRequestsLimit { 18 | p.Max = ConcurrentRequestsLimit 19 | } 20 | 21 | p.Tickets = make(chan *struct{}, p.Max) 22 | for i := 0; i < p.Max; i++ { 23 | p.Tickets <- &struct{}{} 24 | } 25 | 26 | return p 27 | } 28 | 29 | func (p *executorPool) Return(ticket *struct{}) { 30 | if ticket == nil { 31 | return 32 | } 33 | 34 | p.Metrics.Updates <- poolMetricsUpdate{ 35 | activeCount: p.ActiveCount(), 36 | } 37 | p.Tickets <- ticket 38 | } 39 | 40 | func (p *executorPool) ActiveCount() int { 41 | return p.Max - len(p.Tickets) 42 | } 43 | -------------------------------------------------------------------------------- /docs/plugins-tracing/zipkin.md: -------------------------------------------------------------------------------- 1 | # Zipkin 2 | 3 | Zipkin tracer is a plugin of go chassis, it reports tracing data to zipkin server 4 | 5 | ## Configurations 6 | you must import tracing plugin pkg in main.go 7 | ```go 8 | import _ "github.com/go-chassis/go-chassis-extension/tracing/zipkin" 9 | ``` 10 | 11 | **tracing.settings.URI** 12 | > *(optional, string)* zipkin api url 13 | 14 | **tracing.settings.batchSize** 15 | > *(optional, string)* after how many data collected, a tracer will report to server, default is 10000 16 | 17 | **tracing.settings.batchInterval** 18 | > *(optional, string)* after how long the tracer running, a tracer will report to server, default is 10s 19 | 20 | **tracing.settings.collector** 21 | > *(optional, string)* support http, namedPipe, default is http 22 | 23 | 24 | ## Example 25 | ```yaml 26 | tracing: 27 | tracer: zipkin 28 | settings: 29 | URI: http://127.0.0.1:9411/api/v1/spans 30 | batchSize: 10000 31 | batchInterval: 10s 32 | collector: http 33 | 34 | ``` 35 | -------------------------------------------------------------------------------- /pkg/backends/quota/options.go: -------------------------------------------------------------------------------- 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 quota 19 | 20 | //Options is init options 21 | type Options struct { 22 | Endpoint string 23 | Plugin string 24 | } 25 | -------------------------------------------------------------------------------- /docs/dev-guides/circuit.md: -------------------------------------------------------------------------------- 1 | # Circuit breaker 2 | 3 | ## Introduction 4 | go chassis allows you to define how to handle errors, if a remote call fails 5 | 6 | ## Usage 7 | 8 | 1.Implement your fallback logic 9 | 10 | ```go 11 | //Fallback defines how to return response if remote call fails 12 | //a implementation should return a closure to handle the error 13 | //in this closure, if you fallback logic should handle the original error, 14 | //you can return a fallback error to replace the original error 15 | //you can assemble invocation.Response on demand 16 | //in summary the closure defines, if err happens, how to handle it. 17 | type Fallback func(inv *invocation.Invocation, finish chan *invocation.Response) func(error) error 18 | ``` 19 | 20 | 2.Register function to go chassis 21 | ```go 22 | circuit.RegisterFallback("your_fallback", f) 23 | ``` 24 | 25 | 3 operate circuit_breaker.yaml to use custom fallback 26 | 27 | ```yaml 28 | servicecomb: 29 | fallbackpolicy: 30 | Consumer: 31 | policy: your_fallback 32 | ``` -------------------------------------------------------------------------------- /core/config/struct_test.go: -------------------------------------------------------------------------------- 1 | package config_test 2 | 3 | import ( 4 | "github.com/go-chassis/go-chassis/v2/core/config" 5 | stringutil "github.com/go-chassis/go-chassis/v2/pkg/string" 6 | "github.com/stretchr/testify/assert" 7 | "gopkg.in/yaml.v2" 8 | "strings" 9 | "testing" 10 | ) 11 | 12 | func TestRouterConfig(t *testing.T) { 13 | b := []byte(` 14 | servicecomb: 15 | routeRule: 16 | service1: | 17 | # test 18 | - precedence: 1 19 | route: 20 | - tags: 21 | version: latest 22 | weight: 100 23 | `) 24 | c := &config.ServiceComb{} 25 | err := yaml.Unmarshal(b, c) 26 | assert.NoError(t, err) 27 | v, ok := c.Prefix.RouteRule["service1"] 28 | assert.True(t, ok) 29 | 30 | v = strings.TrimSpace(v) 31 | t.Log(v) 32 | type AutoGenerated []int 33 | b2 := stringutil.Str2bytes(v) 34 | r := &config.OneServiceRule{} 35 | err = yaml.Unmarshal(b2, r) 36 | assert.NoError(t, err) 37 | t.Log(r) 38 | assert.Equal(t, 1, r.Len()) 39 | t.Log(r.Value()[0].Precedence) 40 | } 41 | -------------------------------------------------------------------------------- /docs/dev-guides/how-to-extend-protocol.md: -------------------------------------------------------------------------------- 1 | # Protocol 2 | ## 概述 3 | 框架支持[grpc协议](https://github.com/go-chassis/go-chassis-protocol), 4 | 用户可扩展自己的RPC协议,并使用RPCInvoker调用 5 | 6 | ## 如何实现 7 | 8 | --- 9 | 10 | #### 客户端 11 | 12 | * 实现协议的客户端接口 13 | 14 | ```go 15 | type Client interface 16 | ``` 17 | 18 | * 实现以下接口来返回客户端插件 19 | 20 | ```go 21 | func(...clientOption.Option) Client 22 | ``` 23 | 24 | * 安装客户端插件 25 | 26 | ```go 27 | func InstallPlugin(protocol string, f ClientNewFunc) 28 | ``` 29 | 30 | * 处理链默认自带名为transport的handler,他将根据协议名加载对应的协议客户端,指定协议的方式如下 31 | 32 | ```go 33 | invoker.Invoke(ctx, "Server", "HelloServer", "SayHello", 34 | &helloworld.HelloRequest{Name: "Peter"}, 35 | reply, 36 | core.WithProtocol("grpc"), 37 | ) 38 | ``` 39 | 40 | #### 服务端 41 | 42 | * 实现协议的Server端 43 | 44 | ``` 45 | type Server interface 46 | ``` 47 | 48 | * 修改配置文件以启动协议监听 49 | 50 | ``` 51 | servicecomb: 52 | protocols: 53 | grpc: 54 | listenAddress: 127.0.0.1:5000 55 | advertiseAddress: 127.0.0.1:5000 56 | ``` 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /examples/ratelimit/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/go-chassis/go-chassis/v2" 5 | _ "github.com/go-chassis/go-chassis/v2/middleware/ratelimiter" 6 | "github.com/go-chassis/go-chassis/v2/server/restful" 7 | "github.com/go-chassis/openlog" 8 | "net/http" 9 | ) 10 | 11 | type DemoResource struct { 12 | } 13 | 14 | func (r *DemoResource) Limit(b *restful.Context) { 15 | b.ReadResponseWriter().WriteHeader(http.StatusOK) 16 | b.ReadResponseWriter().Write([]byte("ok")) 17 | } 18 | 19 | // URLPatterns returns routes 20 | func (r *DemoResource) URLPatterns() []restful.Route { 21 | return []restful.Route{ 22 | {Method: http.MethodGet, Path: "/limit", ResourceFunc: r.Limit}, 23 | } 24 | } 25 | 26 | //if you use go run main.go instead of binary run, plz export CHASSIS_HOME=/{path}/{to}/{project_root}/ 27 | 28 | func main() { 29 | chassis.RegisterSchema("rest", &DemoResource{}) 30 | if err := chassis.Init(); err != nil { 31 | openlog.Error("Init failed." + err.Error()) 32 | return 33 | } 34 | chassis.Run() 35 | } 36 | -------------------------------------------------------------------------------- /core/config/model/registry.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | //RegistryStruct SC information 4 | type RegistryStruct struct { 5 | Disable bool `yaml:"disabled"` 6 | Type string `yaml:"type"` 7 | Scope string `yaml:"scope"` 8 | AutoDiscovery bool `yaml:"autodiscovery"` 9 | AutoIPIndex bool `yaml:"autoIPIndex"` 10 | Address string `yaml:"address"` 11 | RefreshInterval string `yaml:"refreshInterval"` 12 | Watch bool `yaml:"watch"` 13 | AutoRegister string `yaml:"register"` 14 | APIVersion RegistryAPIVersionStruct `yaml:"api"` 15 | 16 | HealthCheck bool `yaml:"healthCheck"` 17 | CacheIndex bool `yaml:"cacheIndex"` 18 | ConfigPath string `yaml:"configPath"` 19 | } 20 | 21 | // RegistryAPIVersionStruct registry api version structure 22 | type RegistryAPIVersionStruct struct { 23 | Version string `yaml:"version"` 24 | } 25 | -------------------------------------------------------------------------------- /docs/user-guides/service-discovery.md: -------------------------------------------------------------------------------- 1 | # Service Discovery 2 | ## 概述 3 | 4 | Service discovery 是关于如何发现服务的配置。 5 | 和Registry的区别是,他仅负责发现服务,而不负责注册服务 6 | Service Discovery与Registry只能选择其一进行配置 7 | 启用此功能可以与Istio的Pilot集成 8 | 9 | ## 配置 10 | 11 | 服务发现的配置在chassis.yaml。 12 | 13 | **type** 14 | > *(optional, string)* 对接服务中心插件类型,默认为servicecenter,另外可选择pilotv2以及kube 15 | 16 | **NOTE: 当使用kube registry时,发布的service需要指定port name为以下格式 [protocol]-[suffix]** 17 | 18 | **address** 19 | > *(optional, bool)* 服务中心地址 允许配置多个以逗号隔开,默认为空 20 | 21 | **refreshInterval** 22 | > *(optional, string)* 更新实例缓存的时间间隔,格式为数字加单位(s/m/h),如1s/1m/1h,默认为30s 23 | 24 | ## 示例 25 | 26 | 当registry type为pilotv2时需要指定pilot的地址address,当registry type为kube时需要指定与kube-apiserver交互所需的kubeconfig的配置文件位置,以下分别为registry的最小示例。 27 | 28 | ```yaml 29 | servicecomb: 30 | registry: 31 | type: pilotv2 32 | address: grpc://istio-pilot.istio-system:15010 33 | refeshInterval: 30s 34 | ``` 35 | 36 | ```yaml 37 | servicecomb: 38 | registry: 39 | type: kube 40 | configPath: /etc/.kube/config 41 | ``` 42 | 43 | -------------------------------------------------------------------------------- /examples/pilot/server/build/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | 5 | # //////////////////////////////////////////////////////////////////////////// # 6 | # go sdk # 7 | # //////////////////////////////////////////////////////////////////////////// # 8 | 9 | if [ "$CSE_SERVICE_CENTER" ]; then 10 | export CSE_REGISTRY_ADDR=$CSE_SERVICE_CENTER 11 | fi 12 | 13 | if [ "$CSE_CONFIG_CENTER" ]; then 14 | export CSE_CONFIG_CENTER_ADDR=$CSE_CONFIG_CENTER 15 | fi 16 | 17 | name=gosdk-istio-server 18 | 19 | listen_addr="0.0.0.0" 20 | advertise_addr=$(ifconfig eth0 | grep -E 'inet\W' | grep -o -E [0-9]+.[0-9]+.[0-9]+.[0-9]+ | head -n 1) 21 | 22 | cd /home/$name 23 | # replace ip addr 24 | sed -i s/"listenAddress:\s\{1,\}[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}"/"listenAddress: $listen_addr"/g conf/chassis.yaml 25 | sed -i s/"advertiseAddress:\s\{1,\}[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}"/"advertiseAddress: $advertise_addr"/g conf/chassis.yaml 26 | 27 | ./app 28 | -------------------------------------------------------------------------------- /examples/discovery/server/conf/circuit_breaker.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | servicecomb: 3 | isolation: 4 | Consumer: 5 | timeoutInMilliseconds: 10 6 | maxConcurrentRequests: 100 7 | Server: 8 | timeoutInMilliseconds: 1000 9 | maxConcurrentRequests: 100 10 | Provider: 11 | timeoutInMilliseconds: 20 12 | maxConcurrentRequests: 200 13 | circuitBreaker: 14 | Consumer: 15 | enabled: true 16 | forceOpen: false 17 | forceClosed: false 18 | sleepWindowInMilliseconds: 10000 19 | requestVolumeThreshold: 20 20 | errorThresholdPercentage: 50 21 | Server: 22 | enabled: true 23 | forceOpen: true 24 | forceClosed: false 25 | sleepWindowInMilliseconds: 10000 26 | requestVolumeThreshold: 20 27 | errorThresholdPercentage: 50 28 | fallback: 29 | Consumer: 30 | enabled: false 31 | maxConcurrentRequests: 20 32 | fallbackpolicy: 33 | Consumer: 34 | policy: throwexception 35 | Server: 36 | policy: throwexception -------------------------------------------------------------------------------- /examples/circuit/README.md: -------------------------------------------------------------------------------- 1 | # A circuit breaker example to show api level isolation 2 | here is the config 3 | ```yaml 4 | --- 5 | servicecomb: 6 | isolation: 7 | Consumer: 8 | timeoutInMilliseconds: 100 9 | maxConcurrentRequests: 1000 10 | circuitBreaker: 11 | scope: api # service|api 12 | Consumer: 13 | enabled: true 14 | forceOpen: false 15 | forceClosed: false 16 | sleepWindowInMilliseconds: 10000 17 | requestVolumeThreshold: 10 18 | errorThresholdPercentage: 10 19 | fallback: 20 | Consumer: 21 | enabled: true 22 | fallbackpolicy: 23 | Consumer: 24 | policy: throwexception 25 | ``` 26 | time out is 100ms 27 | 28 | client calls a API which has a dead lock, circuit breaker will isolate this API 29 | 30 | client can still call other API of this same service 31 | 32 | if you change scope to "service" 33 | 34 | it will isolate the service 35 | 36 | the runtime metrics is exported by prometheus exporter 37 | check 127.0.0.1:5000/metrics and 127.0.0.1:5001/metrics to observe services -------------------------------------------------------------------------------- /examples/discovery/server/build/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | 5 | # //////////////////////////////////////////////////////////////////////////// # 6 | # go sdk # 7 | # //////////////////////////////////////////////////////////////////////////// # 8 | 9 | if [ "$CSE_SERVICE_CENTER" ]; then 10 | export CSE_REGISTRY_ADDR=$CSE_SERVICE_CENTER 11 | fi 12 | 13 | if [ "$CSE_CONFIG_CENTER" ]; then 14 | export CSE_CONFIG_CENTER_ADDR=$CSE_CONFIG_CENTER 15 | fi 16 | 17 | name=gosdk-discovery-server 18 | 19 | listen_addr="0.0.0.0" 20 | advertise_addr=$(ifconfig eth0 | grep -E 'inet\W' | grep -o -E [0-9]+.[0-9]+.[0-9]+.[0-9]+ | head -n 1) 21 | 22 | cd /home/$name 23 | # replace ip addr 24 | sed -i s/"listenAddress:\s\{1,\}[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}"/"listenAddress: $listen_addr"/g conf/chassis.yaml 25 | sed -i s/"advertiseAddress:\s\{1,\}[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}"/"advertiseAddress: $advertise_addr"/g conf/chassis.yaml 26 | 27 | ./app 28 | -------------------------------------------------------------------------------- /control/servicecomb/loadbalance_event_listener_test.go: -------------------------------------------------------------------------------- 1 | package servicecomb_test 2 | 3 | import ( 4 | "github.com/go-chassis/go-archaius" 5 | "github.com/go-chassis/go-chassis/v2/control/servicecomb" 6 | "github.com/go-chassis/go-chassis/v2/core/config" 7 | "github.com/go-chassis/go-chassis/v2/core/loadbalancer" 8 | "github.com/stretchr/testify/assert" 9 | "testing" 10 | ) 11 | 12 | func TestLbEventError(t *testing.T) { 13 | servicecomb.Init() 14 | archaius.Set("cse.loadbalance.strategy.name", loadbalancer.StrategySessionStickiness) 15 | assert.Equal(t, loadbalancer.StrategySessionStickiness, archaius.GetString("cse.loadbalance.strategy.name", "")) 16 | 17 | archaius.Set("cse.loadbalance.strategy.Server.name", loadbalancer.StrategySessionStickiness) 18 | config.ReadLBFromArchaius() 19 | assert.Equal(t, loadbalancer.StrategySessionStickiness, config.GetStrategyName("", "")) 20 | 21 | archaius.Delete("cse.loadbalance.strategy.name") 22 | assert.NotEqual(t, loadbalancer.StrategySessionStickiness, archaius.GetString("cse.loadbalance.strategy.name", "")) 23 | } 24 | -------------------------------------------------------------------------------- /docs/user-guides/healthz.md: -------------------------------------------------------------------------------- 1 | # Client side health check 2 | 3 | ## 概述 4 | 5 | 客户端健康检查(Health Check)是指客户端对服务端实例缓存进行健康性的判断。 6 | 7 | 在网络分区或延时较大的环境下,客户端可能会出现上报心跳到服务中心失败的情况。导致结果是客户端会收到实例下线事件,并移除本地实例缓存,最终影响业务调用。 8 | 9 | 为防止上述情况发生,go-chassis提供这样的健康检查机制:当客户端监听到某个(或latest)版本的服务端可用实例下降到0个时, 10 | 客户端会在同步移除实例缓存前进行一次健康检查,调用服务端暴露的健康检查接口(RESTful或Highway)并校验其返回值来确认是否要移除实例缓存。 11 | 12 | ## 配置 13 | 14 | ### 服务端注册 15 | 16 | go-chassis默认不会主动注册服务端的健康检查接口,需要用户主动import到项目中。 17 | 18 | ```go 19 | // 注册健康检查接口 20 | import _ "github.com/go-chassis/go-chassis/v2/healthz/provider" 21 | ``` 22 | 23 | 加入上述代码片段后,go-chassis会按照暴露的服务协议类型对应注册健康检查接口,接口描述如下 24 | 25 | * RESTful: 26 | 27 | 1. Method: GET 28 | 1. Path: /healthz 29 | 1. Response: 30 | ```js 31 | { 32 | "appId": "string", 33 | "serviceName": "string", 34 | "version": "string" 35 | } 36 | ``` 37 | 38 | ### 客户端配置 39 | 40 | 客户端健康检查配置在chassis.yaml。 41 | 42 | **healthCheck** 43 | > *(optional, bool)* 允许对服务端的实例做健康检查,默认值为false。 44 | 45 | ###### 示例 46 | 47 | ```yaml 48 | servicecomb: 49 | registry: 50 | healthCheck: true 51 | ``` -------------------------------------------------------------------------------- /core/registry/struct_test.go: -------------------------------------------------------------------------------- 1 | package registry 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "testing" 6 | ) 7 | 8 | func TestMicroServiceInstance_Equal(t *testing.T) { 9 | ins1 := &MicroServiceInstance{ 10 | InstanceID: "1", 11 | ServiceID: "bill", 12 | } 13 | ins2 := &MicroServiceInstance{ 14 | InstanceID: "1", 15 | ServiceID: "bill", 16 | } 17 | assert.True(t, ins1.Equal(ins2)) 18 | 19 | ins3 := &MicroServiceInstance{ 20 | InstanceID: "1", 21 | ServiceID: "bill", 22 | Metadata: map[string]string{ 23 | "a": "b", 24 | "c": "d", 25 | }, 26 | } 27 | ins4 := &MicroServiceInstance{ 28 | InstanceID: "1", 29 | ServiceID: "bill", 30 | Metadata: map[string]string{ 31 | "a": "b", 32 | "c": "d", 33 | }, 34 | } 35 | assert.True(t, ins3.Equal(ins4)) 36 | 37 | ins5 := &MicroServiceInstance{ 38 | InstanceID: "2", 39 | ServiceID: "bill", 40 | } 41 | assert.False(t, ins5.Equal(ins4)) 42 | 43 | ins6 := &MicroServiceInstance{ 44 | InstanceID: "2", 45 | ServiceID: "text", 46 | } 47 | assert.False(t, ins5.Equal(ins6)) 48 | } 49 | -------------------------------------------------------------------------------- /core/loadbalancer/struct_test.go: -------------------------------------------------------------------------------- 1 | package loadbalancer_test 2 | 3 | import ( 4 | "github.com/go-chassis/go-chassis/v2/core/loadbalancer" 5 | "github.com/stretchr/testify/assert" 6 | "testing" 7 | "time" 8 | ) 9 | 10 | func TestProtocolStats_SaveLatency(t *testing.T) { 11 | s := &loadbalancer.ProtocolStats{ 12 | Latency: make([]time.Duration, 0), 13 | Addr: "127.0.0.1:8080", 14 | } 15 | s.CalculateAverageLatency() 16 | 17 | s.SaveLatency(1 * time.Second) 18 | s.SaveLatency(2 * time.Second) 19 | s.CalculateAverageLatency() 20 | assert.Equal(t, 1500*time.Millisecond, s.AvgLatency) 21 | 22 | s.SaveLatency(2 * time.Second) 23 | s.SaveLatency(2 * time.Second) 24 | s.SaveLatency(2 * time.Second) 25 | s.SaveLatency(2 * time.Second) 26 | s.SaveLatency(2 * time.Second) 27 | s.SaveLatency(2 * time.Second) 28 | s.SaveLatency(2 * time.Second) 29 | s.SaveLatency(2 * time.Second) 30 | s.CalculateAverageLatency() 31 | s.SaveLatency(3 * time.Second) 32 | s.SaveLatency(3 * time.Second) 33 | s.CalculateAverageLatency() 34 | assert.Equal(t, 2200*time.Millisecond, s.AvgLatency) 35 | 36 | } 37 | -------------------------------------------------------------------------------- /examples/db.js: -------------------------------------------------------------------------------- 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 | db.createUser( 19 | { 20 | user: "kie", 21 | pwd: "123", 22 | roles:[ 23 | { 24 | role: "readWrite", 25 | db: "kie" 26 | } 27 | ] 28 | } 29 | ); -------------------------------------------------------------------------------- /examples/pilot/client/build/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | 5 | # //////////////////////////////////////////////////////////////////////////// # 6 | # go sdk # 7 | # //////////////////////////////////////////////////////////////////////////// # 8 | 9 | if [ "$CSE_SERVICE_CENTER" ]; then 10 | export CSE_REGISTRY_ADDR=$CSE_SERVICE_CENTER 11 | fi 12 | 13 | if [ "$CSE_CONFIG_CENTER" ]; then 14 | export CSE_CONFIG_CENTER_ADDR=$CSE_CONFIG_CENTER 15 | fi 16 | 17 | name=gosdk-istio-client 18 | 19 | listen_addr="0.0.0.0" 20 | advertise_addr=$(ifconfig eth0 | grep -E 'inet\W' | grep -o -E [0-9]+.[0-9]+.[0-9]+.[0-9]+ | head -n 1) 21 | 22 | cd /home/$name 23 | # replace ip addr 24 | sed -i s/"listenAddress:\s\{1,\}[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}"/"listenAddress: $listen_addr"/g conf/chassis.yaml 25 | sed -i s/"advertiseAddress:\s\{1,\}[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}"/"advertiseAddress: $advertise_addr"/g conf/chassis.yaml 26 | 27 | ./app 28 | 29 | while true; do 30 | sleep 60 31 | done 32 | 33 | -------------------------------------------------------------------------------- /examples/discovery/client/build/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | 5 | # //////////////////////////////////////////////////////////////////////////// # 6 | # go sdk # 7 | # //////////////////////////////////////////////////////////////////////////// # 8 | 9 | if [ "$CSE_SERVICE_CENTER" ]; then 10 | export CSE_REGISTRY_ADDR=$CSE_SERVICE_CENTER 11 | fi 12 | 13 | if [ "$CSE_CONFIG_CENTER" ]; then 14 | export CSE_CONFIG_CENTER_ADDR=$CSE_CONFIG_CENTER 15 | fi 16 | 17 | name=gosdk-discovery-client 18 | 19 | listen_addr="0.0.0.0" 20 | advertise_addr=$(ifconfig eth0 | grep -E 'inet\W' | grep -o -E [0-9]+.[0-9]+.[0-9]+.[0-9]+ | head -n 1) 21 | 22 | cd /home/$name 23 | # replace ip addr 24 | sed -i s/"listenAddress:\s\{1,\}[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}"/"listenAddress: $listen_addr"/g conf/chassis.yaml 25 | sed -i s/"advertiseAddress:\s\{1,\}[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}"/"advertiseAddress: $advertise_addr"/g conf/chassis.yaml 26 | 27 | ./app 28 | 29 | while true; do 30 | sleep 60 31 | done 32 | 33 | -------------------------------------------------------------------------------- /examples/schemas/tracing_hello.go: -------------------------------------------------------------------------------- 1 | package schemas 2 | 3 | import ( 4 | "net/http" 5 | 6 | "log" 7 | 8 | "github.com/go-chassis/go-chassis/v2/client/rest" 9 | "github.com/go-chassis/go-chassis/v2/core" 10 | "github.com/go-chassis/go-chassis/v2/pkg/util/httputil" 11 | rf "github.com/go-chassis/go-chassis/v2/server/restful" 12 | ) 13 | 14 | //TracingHello is a struct 15 | type TracingHello struct { 16 | } 17 | 18 | //Trace is a method 19 | func (r *TracingHello) Trace(b *rf.Context) { 20 | log.Println("tracing===", b.Ctx) 21 | req, err := rest.NewRequest("GET", "http://RESTServerB/sayhello/world", nil) 22 | if err != nil { 23 | b.WriteError(500, err) 24 | return 25 | } 26 | 27 | resp, err := core.NewRestInvoker().ContextDo(b.Ctx, req) 28 | if err != nil { 29 | b.WriteError(500, err) 30 | return 31 | } 32 | defer resp.Body.Close() 33 | b.Write(httputil.ReadBody(resp)) 34 | } 35 | 36 | //URLPatterns helps to respond for corresponding API calls 37 | func (r *TracingHello) URLPatterns() []rf.Route { 38 | return []rf.Route{ 39 | {Method: http.MethodGet, Path: "/trace", ResourceFunc: r.Trace}, 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /control/servicecomb/lager_event_listener_test.go: -------------------------------------------------------------------------------- 1 | package servicecomb_test 2 | 3 | import ( 4 | "github.com/go-chassis/go-archaius/event" 5 | "github.com/go-chassis/go-chassis/v2/control/servicecomb" 6 | "testing" 7 | ) 8 | 9 | func TestLagerEventListener_Event(t *testing.T) { 10 | t.Log("Test lager_event_listener_test.go") 11 | servicecomb.Init() 12 | eventListen := &servicecomb.LagerEventListener{} 13 | t.Log("sending the events for the key logLevel") 14 | 15 | e1 := &event.Event{EventType: "UPDATE", Key: "logLevel", Value: "INFO"} 16 | eventListen.Event(e1) 17 | 18 | e2 := &event.Event{EventType: "UPDATE", Key: "logLevel", Value: "WARN"} 19 | eventListen.Event(e2) 20 | 21 | e3 := &event.Event{EventType: "UPDATE", Key: "logLevel", Value: "ERROR"} 22 | eventListen.Event(e3) 23 | 24 | e4 := &event.Event{EventType: "UPDATE", Key: "logLevel", Value: "FATAL"} 25 | eventListen.Event(e4) 26 | 27 | e5 := &event.Event{EventType: "UPDATE", Key: "logLevel", Value: "BAD"} 28 | eventListen.Event(e5) 29 | 30 | e := &event.Event{EventType: "UPDATE", Key: "logLevel", Value: "DEBUG"} 31 | eventListen.Event(e) 32 | 33 | } 34 | -------------------------------------------------------------------------------- /core/fault/README.md: -------------------------------------------------------------------------------- 1 | #fault 2 | 3 | The fault-injector is used for error (delay / abort) registration, and is generally used on the consumer side of microservices. scenes to be used: 4 | >1. Unit test 5 | >2. The simulation of server crashed; 6 | >3. Analog network freeze 7 | 8 | fault-injector supports two types of processing: 9 | >1. delay: The middleware will delay for a specified time according to a certain probability; 10 | >2. abort: The middleware reports an error according to the probability. If an error occurs, the entire link is interrupted. 11 |   12 | 13 | Implementation principle: 14 | >When the request arrives, for each strategy, an integer [0-100] randVal is randomly generated, and when percentage> = randVal + 1, the strategy is hit 15 | 16 | 17 | Note: 18 | > 1. When delay and abort are configured at the same time, delay is executed first, and then abort is executed; 19 | > 2. The go-chassis framework supports the following protocols by default. If you need other protocols or customization, you need to register through InstallFaultInjectionPlugin. 20 |
rest,
rhighway,
rdubbo 21 | 22 | 23 | -------------------------------------------------------------------------------- /resilience/retry/backoff.go: -------------------------------------------------------------------------------- 1 | package retry 2 | 3 | import ( 4 | "github.com/cenkalti/backoff" 5 | "time" 6 | ) 7 | 8 | //retry kind 9 | const ( 10 | KindExponential = "exponential" 11 | KindConstant = "constant" 12 | KindZero = "zero" 13 | DefaultBackOffKind = KindExponential 14 | ) 15 | 16 | //GetBackOff return the the back off policy 17 | //min and max unit is million second 18 | func GetBackOff(kind string, min, max int) backoff.BackOff { 19 | switch kind { 20 | case KindExponential: 21 | return &backoff.ExponentialBackOff{ 22 | InitialInterval: time.Duration(min) * time.Millisecond, 23 | RandomizationFactor: backoff.DefaultRandomizationFactor, 24 | Multiplier: backoff.DefaultMultiplier, 25 | MaxInterval: time.Duration(max) * time.Millisecond, 26 | MaxElapsedTime: 0, 27 | Clock: backoff.SystemClock, 28 | } 29 | case KindConstant: 30 | return backoff.NewConstantBackOff(time.Duration(min) * time.Millisecond) 31 | case KindZero: 32 | return &backoff.ZeroBackOff{} 33 | default: 34 | return &backoff.ExponentialBackOff{} 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /docs/dev-guides/router.md: -------------------------------------------------------------------------------- 1 | # Router 2 | this guide shows how to customize your own router management. 3 | 4 | ### Introduction 5 | 6 | A Router plugin should has ability to fetch router rule, 7 | it decides where the route rule comes from. 8 | 9 | go chassis has standardized model "config.RouteRule", you must adapt to it 10 | ```go 11 | type Router interface { 12 | Init(Options) error 13 | SetRouteRule(map[string][]*config.RouteRule) 14 | FetchRouteRuleByServiceName(service string) []*config.RouteRule 15 | ListRouteRule() map[string][]*config.RouteRule 16 | } 17 | ``` 18 | ### Usage 19 | First, install your plugin 20 | ```go 21 | router.InstallRouterPlugin("istio", func() (router.Router, error) { 22 | //return your router implementation 23 | }) 24 | ``` 25 | 26 | Second, specify your plugin name in router.yaml 27 | ```yaml 28 | servicecomb: 29 | router: 30 | plugin: istio 31 | address: "xxx" 32 | ``` 33 | 34 | go chassis will use your router implementation as router rule configuration source, 35 | to know how to manage request traffics, 36 | refer to [Router](https://go-chassis.readthedocs.io/en/latest/user-guides/router.html) -------------------------------------------------------------------------------- /docs/user-guides/filter.md: -------------------------------------------------------------------------------- 1 | # Filter 2 | ## 概述 3 | 4 | 负载均衡过滤器实现在负载均衡模块中,它允许开发者定制自己的过滤器,在经过负载均衡策略选择实例前,预先对实例进行筛选。在一次请求调用过程中可以使用多个过滤策略,对从本地cache或服务中心获取的实例组进行过滤,将经过精简的实例组交给负载均衡策略做后续处理。 5 | 6 | ## 配置 7 | 8 | 目前可配的filter只有根据Available Zone Filter。可根据微服务实例的region以及AZ信息进行过滤,优先寻找同Region与AZ的实例。 9 | 10 | ``` 11 | servicecomb: 12 | loadbalance: 13 | serverListFilters: zoneaware 14 | ``` 15 | 16 | 需要配置实例的Datacenter信息 17 | 18 | ``` 19 | region: 20 | name: us-east 21 | availableZone: us-east-1 22 | ``` 23 | 24 | ## API 25 | 26 | go-chassis支持多种实现Filter接口的过滤器。FilterEndpoint支持通过实例访问地址过滤,FilterMD支持通过元数据过滤,FilterProtocol支持通过协议过滤,FilterAvailableZoneAffinity支持根据Zone过滤。 27 | 28 | ```go 29 | type Filter func([]*registry.MicroServiceInstance) []*registry.MicroServiceInstance 30 | ``` 31 | 32 | ## 示例 33 | 34 | 客户端实例过滤器Filter的使用,支持用户通过API调用传入,并且可以一次传入多个Filter, 35 | 36 | ```go 37 | invoker.Invoke(ctx, "Server", "HelloServer", "SayHello", 38 | &helloworld.HelloRequest{Name: "Peter"}, 39 | reply, 40 | core.WithStrategy(loadbalance.StrategyRoundRobin), 41 | core.WithFilters( 42 | "zoneaware" 43 | ), 44 | ) 45 | ``` 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /licenses/LICENSE_jtolds_gls: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013, Space Monkey, Inc. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so, 8 | subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | -------------------------------------------------------------------------------- /third_party/forked/afex/hystrix-go/hystrix/metrics_test.go: -------------------------------------------------------------------------------- 1 | package hystrix 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | 7 | . "github.com/smartystreets/goconvey/convey" 8 | ) 9 | 10 | func metricFailingPercent(p int) *metricExchange { 11 | m := newMetricExchange("", 5) 12 | for i := 0; i < 100; i++ { 13 | t := "success" 14 | if i < p { 15 | t = "failure" 16 | } 17 | m.Updates <- &commandExecution{Types: []string{t}} 18 | } 19 | 20 | // Updates needs to be flushed 21 | time.Sleep(100 * time.Millisecond) 22 | 23 | return m 24 | } 25 | 26 | func TestErrorPercent(t *testing.T) { 27 | Convey("with a metric failing 40 percent of the time", t, func() { 28 | m := metricFailingPercent(40) 29 | now := time.Now() 30 | 31 | Convey("ErrorPercent() should return 40", func() { 32 | p := m.ErrorPercent(now) 33 | So(p, ShouldEqual, 40) 34 | }) 35 | 36 | Convey("and a error threshold set to 39", func() { 37 | ConfigureCommand("", CommandConfig{ErrorPercentThreshold: 39}) 38 | 39 | Convey("the Metrics should be unhealthy", func() { 40 | So(m.IsHealthy(now), ShouldBeFalse) 41 | }) 42 | 43 | }) 44 | }) 45 | } 46 | -------------------------------------------------------------------------------- /licenses/COPYING_alecthomas_units: -------------------------------------------------------------------------------- 1 | Copyright (C) 2014 Alec Thomas 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /licenses/LICENSE_beorn7_perks: -------------------------------------------------------------------------------- 1 | Copyright (C) 2013 Blake Mizerany 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/go-chassis/go-chassis/v2 2 | 3 | require ( 4 | github.com/cenkalti/backoff v2.0.0+incompatible 5 | github.com/dgrijalva/jwt-go v3.2.0+incompatible 6 | github.com/emicklei/go-restful v2.12.0+incompatible 7 | github.com/go-chassis/cari v0.0.0-20201113135522-88c21500ca3f 8 | github.com/go-chassis/foundation v0.1.1-0.20200825060850-b16bf420f7b3 9 | github.com/go-chassis/go-archaius v1.3.6-0.20201103103813-43dd1680ebfb 10 | github.com/go-chassis/go-restful-swagger20 v1.0.3-0.20200310030431-17d80f34264f 11 | github.com/go-chassis/openlog v1.1.2 12 | github.com/go-chassis/seclog v1.3.0 13 | github.com/golang/protobuf v1.4.2 14 | github.com/gorilla/websocket v1.4.0 15 | github.com/hashicorp/go-version v1.0.0 16 | github.com/opentracing/opentracing-go v1.1.0 17 | github.com/patrickmn/go-cache v2.1.0+incompatible 18 | github.com/prometheus/client_golang v0.9.1 19 | github.com/prometheus/common v0.2.0 20 | github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a 21 | github.com/stretchr/testify v1.6.1 22 | gopkg.in/yaml.v2 v2.3.0 23 | k8s.io/apimachinery v0.17.0 24 | k8s.io/client-go v0.17.0 25 | ) 26 | 27 | go 1.13 28 | -------------------------------------------------------------------------------- /core/metadata/framework_metadata_test.go: -------------------------------------------------------------------------------- 1 | package metadata_test 2 | 3 | import ( 4 | "github.com/go-chassis/go-chassis/v2/core/lager" 5 | "github.com/go-chassis/go-chassis/v2/core/metadata" 6 | "github.com/stretchr/testify/assert" 7 | "sync" 8 | "testing" 9 | ) 10 | 11 | func init() { 12 | lager.Init(&lager.Options{ 13 | LoggerLevel: "INFO", 14 | }) 15 | } 16 | func TestFramework(t *testing.T) { 17 | metadata.Once = &sync.Once{} 18 | assert := assert.New(t) 19 | t.Log("Service started by SDK") 20 | f := metadata.NewFramework() 21 | assert.Equal(f.Name, metadata.SdkName) 22 | assert.Equal(f.Version, metadata.SdkVersion) 23 | assert.Equal(f.Register, metadata.SdkRegistrationComponent) 24 | } 25 | 26 | func TestFrameworkSetNameVersionRegister(t *testing.T) { 27 | assert := assert.New(t) 28 | t.Log("setting framework name, version and registration component by exported Method") 29 | f := metadata.NewFramework() 30 | f.SetName("MyFramework") 31 | f.SetVersion("0.5") 32 | f.SetRegister("MyRegistrationComponent") 33 | assert.Equal(f.Name, "MyFramework") 34 | assert.Equal(f.Version, "0.5") 35 | assert.Equal(f.Register, "MyRegistrationComponent") 36 | } 37 | -------------------------------------------------------------------------------- /pkg/scclient/options.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "crypto/tls" 5 | "time" 6 | 7 | "context" 8 | ) 9 | 10 | // Options is the list of dynamic parameter's which can be passed to the RegistryClient while creating a new client 11 | type Options struct { 12 | Addrs []string 13 | EnableSSL bool 14 | Timeout time.Duration 15 | TLSConfig *tls.Config 16 | // Other options can be stored in a context 17 | Context context.Context 18 | Compressed bool 19 | Verbose bool 20 | Version string 21 | } 22 | 23 | //CallOptions is options when you call a API 24 | type CallOptions struct { 25 | WithoutRevision bool 26 | Revision string 27 | WithGlobal bool 28 | } 29 | 30 | //WithoutRevision ignore current revision number 31 | func WithoutRevision() CallOption { 32 | return func(o *CallOptions) { 33 | o.WithoutRevision = true 34 | } 35 | } 36 | 37 | //WithGlobal query resources include other aggregated SC 38 | func WithGlobal() CallOption { 39 | return func(o *CallOptions) { 40 | o.WithGlobal = true 41 | } 42 | } 43 | 44 | //CallOption is receiver for options and chang the attribute of it 45 | type CallOption func(*CallOptions) 46 | -------------------------------------------------------------------------------- /pkg/scclient/util_test.go: -------------------------------------------------------------------------------- 1 | package client_test 2 | 3 | import ( 4 | scregistry "github.com/go-chassis/cari/discovery" 5 | "github.com/go-chassis/go-chassis/v2/core/registry/servicecenter" 6 | "github.com/stretchr/testify/assert" 7 | "testing" 8 | ) 9 | 10 | func TestRegroupInstances(t *testing.T) { 11 | keys := []*scregistry.FindService{ 12 | { 13 | Service: &scregistry.MicroServiceKey{ 14 | ServiceName: "Service1", 15 | }, 16 | }, 17 | { 18 | Service: &scregistry.MicroServiceKey{ 19 | ServiceName: "Service2", 20 | }, 21 | }, 22 | { 23 | Service: &scregistry.MicroServiceKey{ 24 | ServiceName: "Service3", 25 | }, 26 | }, 27 | } 28 | resp := &scregistry.BatchFindInstancesResponse{ 29 | Services: &scregistry.BatchFindResult{ 30 | Updated: []*scregistry.FindResult{ 31 | {Index: 2, 32 | Instances: []*scregistry.MicroServiceInstance{{ 33 | InstanceId: "1", 34 | }}}, 35 | }, 36 | }, 37 | } 38 | m := servicecenter.RegroupInstances(keys, resp) 39 | t.Log(m) 40 | assert.Equal(t, 1, len(m["Service3"])) 41 | assert.Equal(t, 0, len(m["Service1"])) 42 | assert.Equal(t, 0, len(m["Service2"])) 43 | } 44 | -------------------------------------------------------------------------------- /licenses/LICENSE_spf13_cast: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Steve Francia 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /licenses/LICENSE_cenkalti_backoff: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Cenk Altı 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /licenses/LICENSE_json-iterator_go: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 json-iterator 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /licenses/LICENSE.md_go-stack_stack: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Chris Hines 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /licenses/LICENSE_emicklei_go-restful: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012,2013 Ernest Micklei 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /licenses/LICENSE_konsorten_go-windows-terminal-sequences: -------------------------------------------------------------------------------- 1 | (The MIT License) 2 | 3 | Copyright (c) 2017 marvin + konsorten GmbH (open-source@konsorten.de) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /third_party/forked/afex/hystrix-go/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 keith 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /third_party/forked/afex/hystrix-go/hystrix/pool_metrics.go: -------------------------------------------------------------------------------- 1 | package hystrix 2 | 3 | import ( 4 | "sync" 5 | 6 | "github.com/go-chassis/go-chassis/v2/third_party/forked/afex/hystrix-go/hystrix/rolling" 7 | ) 8 | 9 | type poolMetrics struct { 10 | Mutex *sync.RWMutex 11 | Updates chan poolMetricsUpdate 12 | 13 | Name string 14 | MaxActiveRequests *rolling.Number 15 | Executed *rolling.Number 16 | } 17 | 18 | type poolMetricsUpdate struct { 19 | activeCount int 20 | } 21 | 22 | func newPoolMetrics(name string) *poolMetrics { 23 | m := &poolMetrics{} 24 | m.Name = name 25 | m.Updates = make(chan poolMetricsUpdate) 26 | m.Mutex = &sync.RWMutex{} 27 | 28 | m.Reset() 29 | 30 | go m.Monitor() 31 | 32 | return m 33 | } 34 | 35 | func (m *poolMetrics) Reset() { 36 | m.Mutex.Lock() 37 | defer m.Mutex.Unlock() 38 | 39 | m.MaxActiveRequests = rolling.NewNumber() 40 | m.Executed = rolling.NewNumber() 41 | } 42 | 43 | func (m *poolMetrics) Monitor() { 44 | for u := range m.Updates { 45 | m.Mutex.RLock() 46 | 47 | m.Executed.Increment(1) 48 | m.MaxActiveRequests.UpdateMax(float64(u.activeCount)) 49 | 50 | m.Mutex.RUnlock() 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /core/client/client.go: -------------------------------------------------------------------------------- 1 | // Package client is an interface for any protocol's client 2 | package client 3 | 4 | import ( 5 | "context" 6 | "errors" 7 | 8 | "github.com/go-chassis/go-chassis/v2/core/invocation" 9 | ) 10 | 11 | //ErrCanceled means Request is canceled by context management 12 | var ErrCanceled = errors.New("request cancelled") 13 | 14 | //TransportFailure is caused by client call failure 15 | //for example: resp, err = client.Do(req) 16 | //if err is not nil then should wrap original error with TransportFailure 17 | type TransportFailure struct { 18 | Message string 19 | } 20 | 21 | // Error return error message 22 | func (e TransportFailure) Error() string { 23 | return e.Message 24 | } 25 | 26 | // ProtocolClient is the interface to communicate with one kind of ProtocolServer, it is used in transport handler 27 | // rcp protocol client,http protocol client,or you can implement your own 28 | type ProtocolClient interface { 29 | // TODO use invocation.Response as rsp 30 | Call(ctx context.Context, addr string, inv *invocation.Invocation, rsp interface{}) error 31 | String() string 32 | Close() error 33 | ReloadConfigs(Options) 34 | GetOptions() Options 35 | } 36 | -------------------------------------------------------------------------------- /licenses/LICENSE_go-kit_kit: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Peter Bourgon 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /licenses/LICENSE_go-logfmt_logfmt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 go-logfmt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /licenses/LICENSE_sirupsen_logrus: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Simon Eskildsen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /core/registry/endpoint_struct_test.go: -------------------------------------------------------------------------------- 1 | package registry_test 2 | 3 | import ( 4 | "github.com/go-chassis/go-chassis/v2/core/registry" 5 | "github.com/stretchr/testify/assert" 6 | "testing" 7 | ) 8 | 9 | func TestEndPoint(t *testing.T) { 10 | sslEndpoint := "10.0.1.9:1234?" + registry.SSLEnabledQuery 11 | ep, err := registry.NewEndPoint(sslEndpoint) 12 | assert.Nil(t, err, "parse "+sslEndpoint+" error") 13 | assert.True(t, ep.GenEndpoint() == sslEndpoint) 14 | assert.True(t, ep.IsSSLEnable()) 15 | 16 | commonEndpoint := "10.0.1.9:8080" 17 | ep, err = registry.NewEndPoint(commonEndpoint) 18 | assert.Nil(t, err, "parse "+commonEndpoint+" error") 19 | assert.True(t, ep.GenEndpoint() == commonEndpoint) 20 | assert.False(t, ep.IsSSLEnable()) 21 | 22 | noPortSslEndpoint := "10.0.1.9?" + registry.SSLEnabledQuery 23 | ep, err = registry.NewEndPoint(noPortSslEndpoint) 24 | assert.Nil(t, err, "parse "+noPortSslEndpoint+" error") 25 | assert.True(t, ep.IsSSLEnable()) 26 | 27 | sslFalseEndpoint := "10.0.1.9?sslEnabled=false" 28 | ep, err = registry.NewEndPoint(sslFalseEndpoint) 29 | assert.Nil(t, err, "parse "+sslFalseEndpoint+" error") 30 | assert.False(t, ep.IsSSLEnable()) 31 | } 32 | -------------------------------------------------------------------------------- /licenses/LICENSE_go-chassis_go-restful-swagger20: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 Ernest Micklei 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /licenses/LICENSE_go.uber.org_ratelimit: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Uber Technologies, Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /licenses/LICENSE_stretchr_testify: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2012-2018 Mat Ryer and Tyler Bunnell 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /licenses/LICENSE_patrickmn_go-cache: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012-2017 Patrick Mylund Nielsen and the go-cache contributors 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /pkg/runtime/runtime.go: -------------------------------------------------------------------------------- 1 | package runtime 2 | 3 | //Status 4 | const ( 5 | StatusRunning = "UP" 6 | StatusDown = "DOWN" 7 | ) 8 | 9 | //HostName is the host name of service host 10 | var HostName string 11 | 12 | //ServiceID is the service id in registry service 13 | var ServiceID string 14 | 15 | //ServiceName represent self name 16 | var ServiceName string 17 | 18 | //Environment is usually represent as development, testing, production and acceptance 19 | var Environment string 20 | 21 | //Schemas save schema file names(schema IDs) 22 | var Schemas []string 23 | 24 | //App is app info 25 | var App string 26 | 27 | //Version is version info 28 | var Version string 29 | 30 | //MD is service metadata 31 | var MD map[string]string 32 | 33 | //InstanceMD is instance metadata 34 | var InstanceMD map[string]string 35 | 36 | //InstanceID is the instance id in registry service 37 | var InstanceID string 38 | 39 | //InstanceStatus is the current status of instance 40 | var InstanceStatus string 41 | 42 | //NodeIP is the host ip which go chassis running on, if you deploy it in kubernetes 43 | var NodeIP string 44 | 45 | // Init runtime information 46 | func Init() error { 47 | return nil 48 | } 49 | -------------------------------------------------------------------------------- /licenses/LICENSE_opentracing_opentracing-go: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 The OpenTracing Authors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /core/governance/process_test.go: -------------------------------------------------------------------------------- 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 governance 19 | 20 | import ( 21 | "github.com/stretchr/testify/assert" 22 | "testing" 23 | ) 24 | 25 | func TestProcessLimiter(t *testing.T) { 26 | b := []byte(` 27 | match: t 28 | rate: 1 29 | `) 30 | err := ProcessLimiter("servicecomb.rateLimiting.test", string(b)) 31 | assert.NoError(t, err) 32 | } 33 | -------------------------------------------------------------------------------- /core/config/sr_config.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "github.com/go-chassis/go-archaius" 5 | ) 6 | 7 | // GetRegistratorType returns the Type of service registry 8 | func GetRegistratorType() string { 9 | return GlobalDefinition.ServiceComb.Registry.Type 10 | } 11 | 12 | // GetRegistratorAddress returns the Address of service registry 13 | func GetRegistratorAddress() string { 14 | return GlobalDefinition.ServiceComb.Registry.Address 15 | } 16 | 17 | // GetRegistratorScope returns the Scope of service registry 18 | func GetRegistratorScope() string { 19 | return GlobalDefinition.ServiceComb.Registry.Scope 20 | } 21 | 22 | // GetRegistratorAutoRegister returns the AutoRegister of service registry 23 | func GetRegistratorAutoRegister() string { 24 | return GlobalDefinition.ServiceComb.Registry.AutoRegister 25 | } 26 | 27 | // GetRegistratorAPIVersion returns the APIVersion of service registry 28 | func GetRegistratorAPIVersion() string { 29 | return GlobalDefinition.ServiceComb.Registry.APIVersion.Version 30 | } 31 | 32 | // GetRegistratorDisable returns the Disable of service registry 33 | func GetRegistratorDisable() bool { 34 | return archaius.GetBool("servicecomb.registry.disabled", false) 35 | } 36 | -------------------------------------------------------------------------------- /docs/intro/what-is.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | ### What is Go chassis 4 | 5 | Go chassis is a micro service framework for Go developer. you can develop distributed system with go chassis rapidly. 6 | 7 | 8 | ### Why use Go chassis 9 | 10 | go chassis is designed as a protocol-independent framework, any protocol is able to integrate with go chassis and leverage same function like load balancing, 11 | circuit breaker,rate limiting, those function resilient your service 12 | 13 | go chassis makes service observable by bring open tracing and prometheus to it. 14 | 15 | go chassis is flexible, many different modules can be replaced by other implementation, 16 | like registry, metrics, handler chain, config center etc 17 | 18 | With many build-in function like route management, circuit breaker, load balancing, monitoring etc, 19 | your don't need to search and integrate a solution yourself 20 | 21 | go chassis supports Istio platform, Although Istio is a great platform with a service mesh in data plane, 22 | it surely decrease the throughput and increase the latency of your service and cost more CPU usage. 23 | go chassis can bring better performance to go program, you can use Istio configurations to control go chassis. -------------------------------------------------------------------------------- /core/metadata/framework_metadata.go: -------------------------------------------------------------------------------- 1 | package metadata 2 | 3 | import ( 4 | "sync" 5 | ) 6 | 7 | // variables of micro-service framework, mutex variable 8 | var ( 9 | msFramework *Framework 10 | Once = &sync.Once{} 11 | ) 12 | 13 | // Framework is for to represents name, version, registration 14 | type Framework struct { 15 | Name string 16 | Version string 17 | Register string 18 | } 19 | 20 | // SetName is to set the framework name 21 | func (f *Framework) SetName(name string) { 22 | if f != nil { 23 | f.Name = name 24 | } 25 | } 26 | 27 | // SetVersion to set the version of framework 28 | func (f *Framework) SetVersion(version string) { 29 | if f != nil { 30 | f.Version = version 31 | } 32 | } 33 | 34 | // SetRegister to register the framework 35 | func (f *Framework) SetRegister(register string) { 36 | if f != nil { 37 | f.Register = register 38 | } 39 | } 40 | 41 | // NewFramework returns the object of msFramework 42 | func NewFramework() *Framework { 43 | Once.Do(func() { 44 | msFramework = new(Framework) 45 | msFramework.Name = SdkName 46 | msFramework.Version = SdkVersion 47 | msFramework.Register = SdkRegistrationComponent 48 | 49 | }) 50 | return msFramework 51 | } 52 | -------------------------------------------------------------------------------- /licenses/LICENSE_stretchr_objx: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2014 Stretchr, Inc. 4 | Copyright (c) 2017-2018 objx contributors 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /control/servicecomb/qps_event_listener.go: -------------------------------------------------------------------------------- 1 | package servicecomb 2 | 3 | import ( 4 | "fmt" 5 | "github.com/go-chassis/go-archaius/event" 6 | "github.com/go-chassis/go-chassis/v2/resilience/rate" 7 | "github.com/go-chassis/openlog" 8 | 9 | "strings" 10 | 11 | "github.com/go-chassis/go-chassis/v2/core/common" 12 | ) 13 | 14 | //QPSEventListener is a struct used for Event listener 15 | type QPSEventListener struct { 16 | //Key []string 17 | Key string 18 | } 19 | 20 | //Event is a method for QPS event listening 21 | func (el *QPSEventListener) Event(e *event.Event) { 22 | qpsLimiter := rate.GetRateLimiters() 23 | 24 | if strings.Contains(e.Key, "enabled") { 25 | return 26 | } 27 | qps, ok := e.Value.(int) 28 | if !ok { 29 | openlog.Error(fmt.Sprintf("invalid qps config %s", e.Value)) 30 | } 31 | openlog.Info("update rate limiter", openlog.WithTags(openlog.Tags{ 32 | "module": "RateLimiting", 33 | "event": e.EventType, 34 | "value": qps, 35 | })) 36 | switch e.EventType { 37 | case common.Update: 38 | qpsLimiter.UpdateRateLimit(e.Key, qps, qps/5) 39 | case common.Create: 40 | qpsLimiter.UpdateRateLimit(e.Key, qps, qps/5) 41 | case common.Delete: 42 | qpsLimiter.DeleteRateLimiter(e.Key) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /core/server/options.go: -------------------------------------------------------------------------------- 1 | package server 2 | 3 | import ( 4 | "crypto/tls" 5 | "time" 6 | 7 | "github.com/go-chassis/go-chassis/v2/core/provider" 8 | ) 9 | 10 | //Options is the options for service initiating 11 | type Options struct { 12 | Address string 13 | ProtocolServerName string 14 | ChainName string 15 | Provider provider.Provider 16 | TLSConfig *tls.Config 17 | BodyLimit int64 18 | HeaderLimit int 19 | Timeout time.Duration 20 | } 21 | 22 | //RegisterOptions is options when you register a schema to chassis 23 | type RegisterOptions struct { 24 | SchemaID string 25 | RPCSvcDesc interface{} 26 | } 27 | 28 | //RegisterOption is option when you register a schema to chassis 29 | type RegisterOption func(*RegisterOptions) 30 | 31 | //WithSchemaID you can specify a unique id for schema 32 | func WithSchemaID(schemaID string) RegisterOption { 33 | return func(o *RegisterOptions) { 34 | o.SchemaID = schemaID 35 | } 36 | } 37 | 38 | //WithRPCServiceDesc you can set rpc service desc, it cloud be *grpc.ServiceDesc 39 | func WithRPCServiceDesc(RPCSvcDesc interface{}) RegisterOption { 40 | return func(o *RegisterOptions) { 41 | o.RPCSvcDesc = RPCSvcDesc 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /core/tracing/tracer_manager_test.go: -------------------------------------------------------------------------------- 1 | package tracing_test 2 | 3 | import ( 4 | "errors" 5 | "github.com/go-chassis/go-chassis/v2/core/config" 6 | "github.com/go-chassis/go-chassis/v2/core/config/model" 7 | "github.com/go-chassis/go-chassis/v2/core/lager" 8 | "github.com/go-chassis/go-chassis/v2/core/tracing" 9 | "github.com/opentracing/opentracing-go" 10 | "github.com/stretchr/testify/assert" 11 | "testing" 12 | ) 13 | 14 | func test(o map[string]string) (opentracing.Tracer, error) { 15 | return nil, nil 16 | } 17 | func fake(o map[string]string) (opentracing.Tracer, error) { 18 | return nil, errors.New("123") 19 | } 20 | func TestTracerManager(t *testing.T) { 21 | config.GlobalDefinition = &model.GlobalCfg{} 22 | tracing.InstallTracer("test", test) 23 | tracing.InstallTracer("fake", fake) 24 | err := tracing.Init() 25 | assert.NoError(t, err) 26 | config.GlobalDefinition.Tracing = model.TracingStruct{ 27 | Tracer: "test", 28 | } 29 | err = tracing.Init() 30 | assert.NoError(t, err) 31 | 32 | config.GlobalDefinition.Tracing = model.TracingStruct{ 33 | Tracer: "fake", 34 | } 35 | err = tracing.Init() 36 | assert.Error(t, err) 37 | } 38 | func init() { 39 | lager.Init(&lager.Options{ 40 | LoggerLevel: "INFO", 41 | }) 42 | } 43 | -------------------------------------------------------------------------------- /bootstrap/bootstrap.go: -------------------------------------------------------------------------------- 1 | package bootstrap 2 | 3 | import ( 4 | "fmt" 5 | "github.com/go-chassis/openlog" 6 | ) 7 | 8 | var bootstrapPlugins = make([]*PluginItem, 0) 9 | 10 | //PluginItem include name and plugin implementation 11 | type PluginItem struct { 12 | Name string 13 | Plugin Plugin 14 | } 15 | 16 | //Plugin is a interface which declares Init method 17 | type Plugin interface { 18 | Init() error 19 | } 20 | 21 | // Func The Func type is an adapter to allow the use of ordinary functions as bootstrapPlugin. 22 | type Func func() error 23 | 24 | //Init is a method 25 | func (b Func) Init() error { 26 | return b() 27 | } 28 | 29 | //InstallPlugin is a function which installs plugin, 30 | // during initiating of go chassis, plugins will be executed 31 | func InstallPlugin(name string, plugin Plugin) { 32 | bootstrapPlugins = append(bootstrapPlugins, &PluginItem{ 33 | Name: name, 34 | Plugin: plugin, 35 | }) 36 | } 37 | 38 | //Bootstrap will boot plugins in orders 39 | func Bootstrap() { 40 | for _, bp := range bootstrapPlugins { 41 | openlog.Info("Bootstrap " + bp.Name) 42 | if err := bp.Plugin.Init(); err != nil { 43 | openlog.Error(fmt.Sprintf("Failed to init %s. error [%s]", bp.Name, err.Error())) 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /docs/dev-guides/backends.md: -------------------------------------------------------------------------------- 1 | # Backend toolkit sets 2 | 3 | ## Introduction 4 | go chassis allows you to extend backend plugin, like quota management system. 5 | 6 | in fact all backend plugin is design to be a common module, more like a toolkit, 7 | which can be used out of go chassis framework. 8 | 9 | what go chassis does is just making module ready to be called by configuration file. 10 | 11 | this guide only shows you how to use with go chassis. 12 | 13 | ## Usage 14 | the development of plugin has the same pattern, use quota for example. 15 | 16 | 1.Implement and install a new function 17 | ```go 18 | type inMemory struct { 19 | } 20 | func (im *inMemory) GetQuotas(service, domain string) ([]*quota.Quota, error) { 21 | return []*quota.Quota{ 22 | {ResourceName: "cpu", Used: 10, Limit: 20}, {ResourceName: "mem", Used: 10, Limit: 256}, 23 | }, nil 24 | } 25 | ... 26 | ``` 27 | ```go 28 | quota.Install("mock", func() (quota.Manager, error) { 29 | return &inMemory{}, nil 30 | }) 31 | ``` 32 | 33 | 2.Configure it in chassis.yaml 34 | ```yaml 35 | servicecomb: 36 | quota: 37 | plugin: mock 38 | ``` 39 | 40 | 3. just call API before you create a resource 41 | ```go 42 | quota.PreCreate("some cloud service", "some user", "cpu", 2) 43 | ``` -------------------------------------------------------------------------------- /storage/options.go: -------------------------------------------------------------------------------- 1 | package storage 2 | 3 | //Options is yaml file struct to set db config 4 | type Options struct { 5 | URI string `yaml:"uri"` 6 | PoolSize int `yaml:"poolSize"` 7 | SSLEnabled bool `yaml:"sslEnabled"` 8 | RootCA string `yaml:"rootCAFile"` 9 | Timeout string `yaml:"timeout"` 10 | VerifyPeer bool `yaml:"verifyPeer"` 11 | } 12 | 13 | type Option func(opt *Options) 14 | 15 | func PoolSize(poolSize int) Option { 16 | return func(opt *Options) { 17 | opt.PoolSize = poolSize 18 | } 19 | } 20 | 21 | func SSLEnabled(sslEnabled bool) Option { 22 | return func(opt *Options) { 23 | opt.SSLEnabled = sslEnabled 24 | } 25 | } 26 | 27 | func RootCA(rootCAFile string) Option { 28 | return func(opt *Options) { 29 | opt.RootCA = rootCAFile 30 | } 31 | } 32 | 33 | func Timeout(timeout string) Option { 34 | return func(opt *Options) { 35 | opt.Timeout = timeout 36 | } 37 | } 38 | 39 | func VerifyPeer(verifyPeer bool) Option { 40 | return func(opt *Options) { 41 | opt.VerifyPeer = verifyPeer 42 | } 43 | } 44 | 45 | func NewConfig(uri string, opts ...func(opt *Options)) Options { 46 | opt := Options{ 47 | URI: uri, 48 | } 49 | for _, option := range opts { 50 | option(&opt) 51 | } 52 | return opt 53 | } 54 | -------------------------------------------------------------------------------- /docs/control-plane/kube-discovery.md: -------------------------------------------------------------------------------- 1 | # Kubernetes 2 | 3 | Kubernetes discovery is a service discovery choice, it implements ServiceDiscovery Plugin, 4 | which leads go-chassis to do service discovery in kubernetes cluster according to Services. 5 | 6 | ## Import Path 7 | 8 | kube discovery is a service discovery plugin that should import in your application code explicitly. 9 | 10 | ```go 11 | import _ "github.com/go-chassis/go-chassis-extension/registry/kubernetes" 12 | ``` 13 | 14 | ## Configurations 15 | 16 | If you set servicecomb.registry.type as "kube", then "configPath" is necessary to communicate with kubernetes cluster. go-chassis consumer applications will discover k8s Endpoints and Services. 17 | 18 | > NOTE: Provider applications with go-chassis must deploy itself as a k8s Pod asscociate with k8s Service. The Service ports must be named and the port name must be the form **\[-\]**. protocol can set to be `rest` or `grpc` now. 19 | 20 | ```yaml 21 | servicecomb: 22 | registry: 23 | type: kube 24 | configPath: /etc/.kube/config 25 | ``` 26 | 27 | To see the detailed use case of how to use kube discovery 28 | with chassis please refer to this 29 | [example](https://github.com/go-chassis/go-chassis-examples/tree/master/kube). 30 | -------------------------------------------------------------------------------- /examples/rest/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/v2" 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/core/common" 12 | "github.com/go-chassis/go-chassis/v2/pkg/util/httputil" 13 | ) 14 | 15 | //if you use go run main.go instead of binary run, plz export CHASSIS_HOME=/{path}/{to}/rest/client/ 16 | func main() { 17 | //Init framework 18 | if err := chassis.Init(); err != nil { 19 | openlog.Error("Init failed." + err.Error()) 20 | return 21 | } 22 | 23 | req, err := rest.NewRequest("GET", "http://RESTServer/sayhello/world", nil) 24 | if err != nil { 25 | openlog.Error("new request failed.") 26 | return 27 | } 28 | 29 | ctx := context.WithValue(context.TODO(), common.ContextHeaderKey{}, map[string]string{ 30 | "user": "peter", 31 | }) 32 | resp, err := core.NewRestInvoker().ContextDo(ctx, req) 33 | if err != nil { 34 | openlog.Error("do request failed.") 35 | return 36 | } 37 | defer resp.Body.Close() 38 | openlog.Info("REST Server sayhello[GET]: " + string(httputil.ReadBody(resp))) 39 | } 40 | -------------------------------------------------------------------------------- /third_party/forked/afex/hystrix-go/hystrix/pool_test.go: -------------------------------------------------------------------------------- 1 | package hystrix 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | 7 | . "github.com/smartystreets/goconvey/convey" 8 | ) 9 | 10 | func TestReturn(t *testing.T) { 11 | defer Flush() 12 | 13 | Convey("when returning a ticket to the pool", t, func() { 14 | pool := newExecutorPool("pool") 15 | ticket := <-pool.Tickets 16 | pool.Return(ticket) 17 | time.Sleep(1 * time.Millisecond) 18 | Convey("total executed requests should increment", func() { 19 | So(pool.Metrics.Executed.Sum(time.Now()), ShouldEqual, 1) 20 | }) 21 | }) 22 | } 23 | 24 | func TestActiveCount(t *testing.T) { 25 | defer Flush() 26 | 27 | Convey("when 3 tickets are pulled", t, func() { 28 | pool := newExecutorPool("pool") 29 | <-pool.Tickets 30 | <-pool.Tickets 31 | ticket := <-pool.Tickets 32 | 33 | Convey("ActiveCount() should be 3", func() { 34 | So(pool.ActiveCount(), ShouldEqual, 3) 35 | }) 36 | 37 | Convey("and one is returned", func() { 38 | pool.Return(ticket) 39 | 40 | Convey("max active requests should be 3", func() { 41 | time.Sleep(1 * time.Millisecond) // allow poolMetrics to process channel 42 | So(pool.Metrics.MaxActiveRequests.Max(time.Now()), ShouldEqual, 3) 43 | }) 44 | }) 45 | }) 46 | } 47 | -------------------------------------------------------------------------------- /pkg/tool/debug.go: -------------------------------------------------------------------------------- 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 tool 19 | 20 | import ( 21 | "fmt" 22 | "runtime" 23 | ) 24 | 25 | //GetStackTrace get stack trace 26 | func GetStackTrace(skip int) string { 27 | var stacktrace string 28 | for i := skip; ; i++ { 29 | _, f, l, got := runtime.Caller(i) 30 | if !got { 31 | break 32 | } 33 | stacktrace += fmt.Sprintf("%s:%d\n", f, l) 34 | fmt.Println(stacktrace) 35 | } 36 | return stacktrace 37 | } 38 | -------------------------------------------------------------------------------- /core/lager/lager_test.go: -------------------------------------------------------------------------------- 1 | package lager_test 2 | 3 | import ( 4 | "github.com/go-chassis/go-chassis/v2/core/lager" 5 | "github.com/go-chassis/openlog" 6 | "os" 7 | "path/filepath" 8 | "testing" 9 | "time" 10 | ) 11 | 12 | func TestInitialize1(t *testing.T) { 13 | lager.Init(&lager.Options{ 14 | LoggerFile: filepath.Join("./log", "chassis.log"), 15 | Writers: "file", 16 | }) 17 | 18 | if _, err := os.Stat("log"); err != nil { 19 | if os.IsNotExist(err) { 20 | t.Error(err) 21 | } 22 | } 23 | 24 | t.Log("duplicate initialization") 25 | lager.Init(&lager.Options{}) 26 | } 27 | 28 | func TestInitialize2(t *testing.T) { 29 | path := os.Getenv("GOPATH") 30 | logDir := filepath.Join(path, "src", "github.com", "go-chassis", "go-chassis", "examples", "discovery", "server") 31 | os.Setenv("CHASSIS_HOME", logDir) 32 | 33 | //initializing config for to initialize PassLagerDefinition variable 34 | t.Log("initializing config for to initialize PassLagerDefinition variable") 35 | 36 | //Initializing lager 37 | lager.Init(&lager.Options{LoggerLevel: "INFO"}) 38 | openlog.Debug("no output") 39 | openlog.Info("output") 40 | if _, err := os.Stat(logDir); err != nil { 41 | if os.IsNotExist(err) { 42 | t.Error(err) 43 | } 44 | } 45 | 46 | time.Sleep(1 * time.Second) 47 | } 48 | -------------------------------------------------------------------------------- /licenses/Readme_kr_logfmt: -------------------------------------------------------------------------------- 1 | Go package for parsing (and, eventually, generating) 2 | log lines in the logfmt style. 3 | 4 | See http://godoc.org/github.com/kr/logfmt for format, and other documentation and examples. 5 | 6 | Copyright (C) 2013 Keith Rarick, Blake Mizerany 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 11 | 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 13 | -------------------------------------------------------------------------------- /examples/circuit/server/resource/restful_hello.go: -------------------------------------------------------------------------------- 1 | package resource 2 | 3 | import ( 4 | "errors" 5 | "net/http" 6 | "sync" 7 | 8 | rf "github.com/go-chassis/go-chassis/v2/server/restful" 9 | ) 10 | 11 | var l sync.Mutex 12 | 13 | //RestFulMessage is a struct used to implement restful message 14 | type RestFulMessage struct { 15 | } 16 | 17 | //DeadLock is used to simulate deadlock 18 | func (r *RestFulMessage) DeadLock(b *rf.Context) { 19 | l.Lock() 20 | b.Write([]byte("hello world")) 21 | } 22 | 23 | //Sayhi is a method used to reply request user with hello world text 24 | func (r *RestFulMessage) Sayhi(b *rf.Context) { 25 | b.Write([]byte("hello world")) 26 | return 27 | } 28 | 29 | //Sayerror is a method used to reply request user with error 30 | func (r *RestFulMessage) Sayerror(b *rf.Context) { 31 | _ = b.WriteError(http.StatusInternalServerError, errors.New("test hystric")) 32 | return 33 | } 34 | 35 | //URLPatterns helps to respond for corresponding API calls 36 | func (r *RestFulMessage) URLPatterns() []rf.Route { 37 | return []rf.Route{ 38 | {Method: http.MethodGet, Path: "/lock", ResourceFunc: r.DeadLock}, 39 | {Method: http.MethodGet, Path: "/sayhimessage", ResourceFunc: r.Sayhi}, 40 | {Method: http.MethodGet, Path: "/sayerror", ResourceFunc: r.Sayerror}, 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /third_party/forked/afex/hystrix-go/hystrix/settings_test.go: -------------------------------------------------------------------------------- 1 | package hystrix 2 | 3 | import ( 4 | "github.com/smartystreets/goconvey/convey" 5 | "testing" 6 | "time" 7 | ) 8 | 9 | func TestConfigureConcurrency(t *testing.T) { 10 | convey.Convey("given a command configured for 100 concurrent requests", t, func() { 11 | ConfigureCommand("", CommandConfig{MaxConcurrentRequests: 100}) 12 | 13 | convey.Convey("reading the concurrency should be the same", func() { 14 | convey.So(getSettings("").MaxConcurrentRequests, convey.ShouldEqual, 100) 15 | }) 16 | }) 17 | } 18 | 19 | func TestConfigureRVT(t *testing.T) { 20 | convey.Convey("given a command configured to need 30 requests before tripping the circuit", t, func() { 21 | ConfigureCommand("", CommandConfig{RequestVolumeThreshold: 30}) 22 | 23 | convey.Convey("reading the threshold should be the same", func() { 24 | convey.So(getSettings("").RequestVolumeThreshold, convey.ShouldEqual, uint64(30)) 25 | }) 26 | }) 27 | } 28 | 29 | func TestSleepWindowDefault(t *testing.T) { 30 | convey.Convey("given default settings", t, func() { 31 | ConfigureCommand("", CommandConfig{}) 32 | 33 | convey.Convey("the sleep window should be 5 seconds", func() { 34 | convey.So(getSettings("").SleepWindow, convey.ShouldEqual, time.Duration(5*time.Second)) 35 | }) 36 | }) 37 | } 38 | -------------------------------------------------------------------------------- /core/config/archaius.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "github.com/go-chassis/go-archaius" 5 | "github.com/go-chassis/go-chassis/v2/pkg/util/fileutil" 6 | "time" 7 | ) 8 | 9 | // InitArchaius initialize the archaius 10 | func InitArchaius() error { 11 | var err error 12 | 13 | requiredFiles := []string{ 14 | fileutil.GlobalConfigPath(), 15 | fileutil.MicroServiceConfigPath(), 16 | } 17 | optionalFiles := []string{ 18 | fileutil.CircuitBreakerConfigPath(), 19 | fileutil.LoadBalancingConfigPath(), 20 | fileutil.RateLimitingFile(), 21 | fileutil.TLSConfigPath(), 22 | fileutil.MonitoringConfigPath(), 23 | fileutil.AuthConfigPath(), 24 | fileutil.TracingPath(), 25 | fileutil.LogConfigPath(), 26 | fileutil.RouterConfigPath(), 27 | } 28 | 29 | err = archaius.Init( 30 | archaius.WithCommandLineSource(), 31 | archaius.WithMemorySource(), 32 | archaius.WithENVSource(), 33 | archaius.WithRequiredFiles(requiredFiles), 34 | archaius.WithOptionalFiles(optionalFiles)) 35 | 36 | return err 37 | } 38 | 39 | // GetTimeoutDurationFromArchaius get timeout durations from archaius 40 | func GetTimeoutDurationFromArchaius(service, t string) time.Duration { 41 | timeout := archaius.GetInt(GetTimeoutKey(service), archaius.GetInt(GetDefaultTimeoutKey(t), DefaultTimeout)) 42 | return time.Duration(timeout) * time.Millisecond 43 | } 44 | -------------------------------------------------------------------------------- /core/router/router_config_test.go: -------------------------------------------------------------------------------- 1 | package router_test 2 | 3 | import ( 4 | "errors" 5 | "github.com/go-chassis/go-chassis/v2/core/config" 6 | "github.com/go-chassis/go-chassis/v2/core/router" 7 | _ "github.com/go-chassis/go-chassis/v2/initiator" 8 | "github.com/stretchr/testify/assert" 9 | "testing" 10 | ) 11 | 12 | func TestInit(t *testing.T) { 13 | config.Init() 14 | t.Run("install and build a wrong router,return err", func(t *testing.T) { 15 | router.InstallRouterPlugin("wrong", func() (router.Router, error) { 16 | return nil, errors.New("1") 17 | }) 18 | err := router.BuildRouter("wrong") 19 | assert.Error(t, err) 20 | }) 21 | t.Run("validate rule, exact 100, should success", func(t *testing.T) { 22 | ok := router.ValidateRule(map[string][]*config.RouteRule{ 23 | "service1": { 24 | {Routes: []*config.RouteTag{{Weight: 50}, {Weight: 50}}}, 25 | }, 26 | }) 27 | assert.True(t, ok) 28 | }) 29 | t.Run("validate rule, greater than 100, should fail", func(t *testing.T) { 30 | ok := router.ValidateRule(map[string][]*config.RouteRule{ 31 | "service2": { 32 | {Routes: []*config.RouteTag{{Weight: 900}, {Weight: 50}}}, 33 | }, 34 | }) 35 | assert.False(t, ok) 36 | }) 37 | 38 | } 39 | 40 | func BenchmarkGenWeightPoolKey(b *testing.B) { 41 | for i := 0; i < b.N; i++ { 42 | router.GenWeightPoolKey("test", 1) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /middleware/ratelimiter/qps_provider_flow_control_handler.go: -------------------------------------------------------------------------------- 1 | package ratelimiter 2 | 3 | import ( 4 | "github.com/go-chassis/go-chassis/v2/control" 5 | "github.com/go-chassis/go-chassis/v2/core/common" 6 | "github.com/go-chassis/go-chassis/v2/core/handler" 7 | "github.com/go-chassis/go-chassis/v2/core/invocation" 8 | "github.com/go-chassis/go-chassis/v2/resilience/rate" 9 | ) 10 | 11 | // ProviderRateLimiterHandler provider rate limiter handler 12 | type ProviderRateLimiterHandler struct{} 13 | 14 | // Handle is to handle provider rateLimiter things 15 | func (rl *ProviderRateLimiterHandler) Handle(chain *handler.Chain, i *invocation.Invocation, cb invocation.ResponseCallBack) { 16 | rlc := control.DefaultPanel.GetRateLimiting(*i, common.Provider) 17 | if !rlc.Enabled { 18 | chain.Next(i, cb) 19 | 20 | return 21 | } 22 | //qps rate <=0 23 | if rlc.Rate <= 0 { 24 | r := newErrResponse(i) 25 | cb(r) 26 | return 27 | } 28 | if rate.GetRateLimiters().TryAccept(rlc.Key, rlc.Rate, rlc.Rate/5) { 29 | chain.Next(i, cb) 30 | } else { 31 | r := newErrResponse(i) 32 | cb(r) 33 | } 34 | } 35 | 36 | func newProviderRateLimiterHandler() handler.Handler { 37 | return &ProviderRateLimiterHandler{} 38 | } 39 | 40 | // Name returns the name providerratelimiter 41 | func (rl *ProviderRateLimiterHandler) Name() string { 42 | return "providerratelimiter" 43 | } 44 | -------------------------------------------------------------------------------- /third_party/forked/afex/hystrix-go/hystrix/rolling/rolling_test.go: -------------------------------------------------------------------------------- 1 | package rolling 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | 7 | . "github.com/smartystreets/goconvey/convey" 8 | ) 9 | 10 | func TestMax(t *testing.T) { 11 | 12 | Convey("when adding values to a rolling number", t, func() { 13 | n := NewNumber() 14 | for _, x := range []float64{10, 11, 9} { 15 | n.UpdateMax(x) 16 | time.Sleep(1 * time.Second) 17 | } 18 | 19 | Convey("it should know the maximum", func() { 20 | So(n.Max(time.Now()), ShouldEqual, 11) 21 | }) 22 | }) 23 | } 24 | 25 | func TestAvg(t *testing.T) { 26 | Convey("when adding values to a rolling number", t, func() { 27 | n := NewNumber() 28 | for _, x := range []float64{0.5, 1.5, 2.5, 3.5, 4.5} { 29 | n.Increment(x) 30 | time.Sleep(1 * time.Second) 31 | } 32 | 33 | Convey("it should calculate the average over the number of configured buckets", func() { 34 | So(n.Avg(time.Now()), ShouldEqual, 1.25) 35 | }) 36 | }) 37 | } 38 | 39 | func BenchmarkRollingNumberIncrement(b *testing.B) { 40 | n := NewNumber() 41 | 42 | b.ResetTimer() 43 | 44 | for i := 0; i < b.N; i++ { 45 | n.Increment(1) 46 | } 47 | } 48 | 49 | func BenchmarkRollingNumberUpdateMax(b *testing.B) { 50 | n := NewNumber() 51 | 52 | b.ResetTimer() 53 | 54 | for i := 0; i < b.N; i++ { 55 | n.UpdateMax(float64(i)) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /examples/pilot/client/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "github.com/go-chassis/openlog" 6 | "log" 7 | "time" 8 | 9 | "github.com/go-chassis/go-chassis/v2" 10 | _ "github.com/go-chassis/go-chassis/v2/bootstrap" 11 | "github.com/go-chassis/go-chassis/v2/client/rest" 12 | "github.com/go-chassis/go-chassis/v2/core" 13 | "github.com/go-chassis/go-chassis/v2/pkg/util/httputil" 14 | ) 15 | 16 | //if you use go run main.go instead of binary run, plz export CHASSIS_HOME=/path/to/conf/folder 17 | func main() { 18 | //chassis operation 19 | if err := chassis.Init(); err != nil { 20 | openlog.Error("Init failed." + err.Error()) 21 | return 22 | } 23 | restInvoker := core.NewRestInvoker() 24 | 25 | // use the configured chain 26 | for { 27 | callRest(restInvoker, 10) 28 | <-time.After(time.Second) 29 | } 30 | } 31 | 32 | func callRest(invoker *core.RestInvoker, i int) { 33 | url := "http://istioserver/sayhello/b" 34 | if i < 10 { 35 | url = "http://istioserver/sayhello/a" 36 | } 37 | req, _ := rest.NewRequest("GET", url, nil) 38 | //use the invoker like http client. 39 | resp1, err := invoker.ContextDo(context.TODO(), req) 40 | if err != nil { 41 | log.Println(err) 42 | } 43 | log.Println(i, "REST SayHello ------------------------------ ", resp1.StatusCode, string(httputil.ReadBody(resp1))) 44 | 45 | resp1.Body.Close() 46 | } 47 | -------------------------------------------------------------------------------- /core/marker/operator.go: -------------------------------------------------------------------------------- 1 | package marker 2 | 3 | import ( 4 | "regexp" 5 | "strconv" 6 | "strings" 7 | ) 8 | 9 | func exact(value, express string) bool { 10 | return value == express 11 | } 12 | 13 | func contains(value, express string) bool { 14 | return strings.Contains(value, express) 15 | } 16 | 17 | func regex(value, express string) bool { 18 | reg := regexp.MustCompilePOSIX(express) 19 | return reg.Match([]byte(value)) 20 | } 21 | 22 | func noEqu(value, express string) bool { 23 | return !(value == express) 24 | } 25 | 26 | func noLess(value, express string) bool { 27 | return cmpInt(value, express, func(v, e int) bool { 28 | return v >= e 29 | }) 30 | } 31 | 32 | func less(value, express string) bool { 33 | return cmpInt(value, express, func(v, e int) bool { 34 | return v < e 35 | }) 36 | } 37 | 38 | func noGreater(value, express string) bool { 39 | return cmpInt(value, express, func(v, e int) bool { 40 | return v <= e 41 | }) 42 | } 43 | 44 | func greater(value, express string) bool { 45 | return cmpInt(value, express, func(v, e int) bool { 46 | return v > e 47 | }) 48 | } 49 | 50 | func cmpInt(value, express string, op func(v, e int) bool) bool { 51 | v, err := strconv.Atoi(value) 52 | if err != nil { 53 | return false 54 | } 55 | exp, err := strconv.Atoi(express) 56 | if err != nil { 57 | return false 58 | } 59 | return op(v, exp) 60 | } 61 | -------------------------------------------------------------------------------- /core/endpoint/endpoint.go: -------------------------------------------------------------------------------- 1 | package endpoint 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "github.com/go-chassis/go-chassis/v2/core/registry" 7 | "github.com/go-chassis/go-chassis/v2/pkg/runtime" 8 | "github.com/go-chassis/go-chassis/v2/pkg/util/tags" 9 | "github.com/go-chassis/openlog" 10 | ) 11 | 12 | //GetEndpoint is an API used to get the endpoint of a service in discovery service 13 | //it will only return endpoints of a service 14 | func GetEndpoint(appID, microService, version string) (string, error) { 15 | var endpoint string 16 | tags := utiltags.NewDefaultTag(version, appID) 17 | instances, err := registry.DefaultServiceDiscoveryService.FindMicroServiceInstances(runtime.ServiceID, microService, tags) 18 | if err != nil { 19 | openlog.Warn(fmt.Sprintf("Get service instance failed, for key: %s:%s:%s", 20 | appID, microService, version)) 21 | return "", err 22 | } 23 | 24 | if len(instances) == 0 { 25 | instanceError := fmt.Sprintf("No available instance, key: %s:%s:%s", 26 | appID, microService, version) 27 | return "", errors.New(instanceError) 28 | } 29 | 30 | for _, instance := range instances { 31 | for _, value := range instance.EndpointsMap { 32 | if value.IsSSLEnable() { 33 | endpoint = "https://" + value.Address 34 | } else { 35 | endpoint = "http://" + value.Address 36 | } 37 | } 38 | } 39 | 40 | return endpoint, nil 41 | } 42 | -------------------------------------------------------------------------------- /core/marker/operator_test.go: -------------------------------------------------------------------------------- 1 | package marker 2 | 3 | import ( 4 | "fmt" 5 | "github.com/stretchr/testify/assert" 6 | "testing" 7 | ) 8 | 9 | func TestOperator(t *testing.T) { 10 | testCase := map[string]struct { 11 | op string 12 | value string 13 | express string 14 | result bool 15 | }{ 16 | "1": { 17 | "noEqu", 18 | "1", 19 | "2", 20 | true, 21 | }, 22 | "2": { 23 | "noEqu", 24 | "2", 25 | "2", 26 | false, 27 | }, 28 | "3": { 29 | "noLess", 30 | "3", 31 | "2", 32 | true, 33 | }, 34 | "4": { 35 | "noLess", 36 | "3", 37 | "3", 38 | true, 39 | }, 40 | "5": { 41 | "less", 42 | "3", 43 | "4", 44 | true, 45 | }, 46 | "6": { 47 | "less", 48 | "3", 49 | "3", 50 | false, 51 | }, 52 | "7": { 53 | "noGreater", 54 | "3", 55 | "3", 56 | true, 57 | }, 58 | "8": { 59 | "noGreater", 60 | "2", 61 | "3", 62 | true, 63 | }, 64 | "9": { 65 | "greater", 66 | "3", 67 | "3", 68 | false, 69 | }, 70 | "10": { 71 | "greater", 72 | "3", 73 | "2", 74 | true, 75 | }, 76 | } 77 | 78 | for _, tc := range testCase { 79 | f, err := operatorPlugin[tc.op] 80 | assert.NotNil(t, err) 81 | assert.Equal(t, tc.result, f(tc.value, tc.express), 82 | fmt.Sprintf("test value %s op %s exp %s faile", tc.value, tc.op, tc.express)) 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /server/restful/handler.go: -------------------------------------------------------------------------------- 1 | package restful 2 | 3 | import ( 4 | "github.com/go-chassis/go-chassis/v2/core/handler" 5 | "github.com/go-chassis/go-chassis/v2/core/invocation" 6 | "github.com/go-chassis/go-chassis/v2/core/server" 7 | "net/http" 8 | ) 9 | 10 | // ResourceHandler wraps go-chassis restful function 11 | type ResourceHandler struct { 12 | handleFunc func(ctx *Context) 13 | rc *Context 14 | opts server.Options 15 | } 16 | 17 | // Handle is to handle the router related things 18 | func (h *ResourceHandler) Handle(chain *handler.Chain, inv *invocation.Invocation, cb invocation.ResponseCallBack) { 19 | Invocation2HTTPRequest(inv, h.rc.Req) 20 | 21 | // check body size 22 | if h.opts.BodyLimit > 0 { 23 | h.rc.Req.Request.Body = http.MaxBytesReader(h.rc.Resp, h.rc.Req.Request.Body, h.opts.BodyLimit) 24 | } 25 | 26 | h.rc.Ctx = inv.Ctx 27 | // call real route func 28 | h.handleFunc(h.rc) 29 | ir := &invocation.Response{} 30 | ir.Status = h.rc.Resp.StatusCode() 31 | ir.Result = h.rc.Resp 32 | //call next chain 33 | cb(ir) 34 | } 35 | 36 | func newHandler(f func(ctx *Context), rc *Context, opts server.Options) handler.Handler { 37 | return &ResourceHandler{ 38 | handleFunc: f, 39 | rc: rc, 40 | opts: opts, 41 | } 42 | } 43 | 44 | // Name returns the name string 45 | func (h *ResourceHandler) Name() string { 46 | return "restful" 47 | } 48 | -------------------------------------------------------------------------------- /licenses/LICENSE.md_smartystreets_goconvey: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 SmartyStreets, LLC 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | 21 | NOTE: Various optional and subordinate components carry their own licensing 22 | requirements and restrictions. Use of those components is subject to the terms 23 | and conditions outlined the respective license of each component. 24 | -------------------------------------------------------------------------------- /docs/user-guides/profile.md: -------------------------------------------------------------------------------- 1 | # Profiling 2 | ## Overview 3 | 4 | Go-chassis provides the ability to inquire route rules and discovered microservice instance information in the current program cache when the program is running. 5 | 6 | It allows users to easily locate issues of route and service discovery. 7 | 8 | ## Configurations 9 | 10 | **cse.profile.enable** 11 | > *(optional, bool)* If it is true, 12 | a new http API defined in "cse.profile.apiPath" will serve for client. 13 | Default is *false*. 14 | 15 | **cse.profile.apiPath** 16 | > *(optional, string)* It's the root path of the profile interface, 17 | default is */profile*. 18 | The specific profile path will be under this root path. 19 | 20 | 21 | ## Example 22 | 23 | ```yaml 24 | servicecomb: 25 | profile: 26 | enable: true 27 | apiPath: /profile 28 | ``` 29 | 30 | If the rest is listening on 127.0.0.1:8080, after performing the above configuration, 31 | you can get route rules through [http://127.0.0.1:8080/profile/route-rule](http://127.0.0.1:8080/profile/route-rule) and 32 | discovered microservice instance information through [http://127.0.0.1:8080/profile/discovery](http://127.0.0.1:8080/profile/discovery). 33 | 34 | Or you can get all profile data through root path [http://127.0.0.1:8080/profile](http://127.0.0.1:8080/profile). 35 | It includes information for all the above sub-paths. 36 | 37 | -------------------------------------------------------------------------------- /licenses/LICENSE_gopherjs_gopherjs: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Richard Musiol. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 15 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 16 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 17 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 18 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 19 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 20 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | --------------------------------------------------------------------------------