├── .DS_Store ├── .gitignore ├── LICENSE ├── LRU ├── list.go └── lru_test.go ├── NATS_streaming └── main.go ├── README.md ├── active_object ├── active_object.go └── main.go ├── all_packaged_library ├── README.md ├── base │ ├── base.go │ ├── config │ │ ├── config.go │ │ ├── minio.go │ │ ├── mongodb.go │ │ ├── mysql.go │ │ ├── redis.go │ │ ├── server.go │ │ └── tool.go │ ├── db.ini │ ├── db │ │ ├── db.go │ │ ├── minio.go │ │ ├── mongodb.go │ │ ├── mysql.go │ │ └── redis.go │ ├── tool.ini │ └── tool │ │ ├── log.go │ │ ├── redis_lock.go │ │ ├── signal.go │ │ ├── snow_flake.go │ │ ├── tool.go │ │ └── utils.go ├── logtool │ ├── log.go │ └── log_test.go ├── nginx-statistics │ ├── test.log │ └── watch.go ├── perf │ ├── perf.go │ └── perf_test.go ├── push │ ├── apple_pushkit │ │ ├── pushkit_push.go │ │ └── pushkit_test.go │ ├── firebase │ │ └── filebase.go │ └── huawei │ │ ├── bean.go │ │ ├── huawei_test.go │ │ └── push.go └── quit │ └── signal.go ├── cli └── main.go ├── container └── heap │ ├── heap.go │ └── heap_test.go ├── context ├── go_ctx.go └── main.go ├── ddd-auth2-example ├── README.md ├── adpter │ ├── adpter.go │ └── http │ │ ├── auth_handles │ │ ├── auth_code_handles.go │ │ ├── auth_token_handles.go │ │ └── handers.go │ │ ├── http.go │ │ └── routers │ │ ├── middleware.go │ │ └── routers.go ├── cmd │ ├── app.yaml │ ├── main.go │ ├── wire.go │ └── wire_gen.go ├── domain │ ├── aggregate │ │ ├── auth_code.go │ │ ├── auth_factory.go │ │ ├── auth_token.go │ │ ├── auth_token_produce.go │ │ └── factory.go │ ├── dto │ │ ├── auth_code.go │ │ ├── auth_token.go │ │ └── user.go │ ├── entity │ │ └── merchant.go │ ├── obj │ │ ├── auth_code.go │ │ └── auth_token.go │ ├── repo │ │ ├── auth_code.go │ │ ├── auth_token.go │ │ ├── merchant.go │ │ └── specification │ │ │ ├── auth_code_by_code.go │ │ │ ├── auth_token_by_code.go │ │ │ └── merchant_by_appid.go │ └── service │ │ ├── auth_code.go │ │ ├── auth_token.go │ │ ├── merchant.go │ │ └── service.go └── infrastructure │ ├── conf │ ├── auth_consts.go │ └── conf.go │ ├── pkg │ ├── database │ │ ├── mongo │ │ │ └── mgo.go │ │ └── redis │ │ │ ├── lock.go │ │ │ └── redis.go │ ├── hcode │ │ ├── base.go │ │ └── code.go │ ├── log │ │ └── zap.go │ └── tool │ │ ├── aes.go │ │ ├── aes_test.go │ │ ├── jwt.go │ │ └── jwt_test.go │ └── repository │ ├── atuh_code.go │ ├── atuh_token.go │ ├── merchant.go │ └── repository.go ├── ddd-project-example ├── README.md ├── adapter │ ├── facade │ │ └── .gitignore │ ├── grpc │ │ └── .gitignore │ └── http │ │ └── .gitignore ├── application │ ├── assembler │ │ └── .gitignore │ ├── cqe │ │ └── .gitignore │ ├── dto │ │ └── .gitignore │ └── service │ │ └── .gitignore ├── cmd │ └── .gitignore ├── domain │ ├── aggregate │ │ └── .gitignore │ ├── entity │ │ └── .gitignore │ ├── event │ │ ├── publish │ │ │ └── .gitignore │ │ └── subsctibe │ │ │ └── .gitignore │ ├── repo │ │ └── specification │ │ │ └── .gitignore │ ├── service │ │ └── .gitignore │ └── vo │ │ └── .gitignore ├── infrastructure │ ├── config │ │ └── .gitignore │ ├── pkg │ │ └── .gitignore │ └── repository │ │ ├── converter │ │ └── .gitignore │ │ └── do │ │ └── .gitignore └── types │ └── .gitignore ├── design-patterns ├── README.md ├── active_object │ ├── active_object.go │ └── main.go ├── builder │ ├── builder.go │ └── main.go ├── chainOfResponsibility │ ├── chainofresponsibility.go │ ├── main.go │ └── task.go └── options │ ├── main.go │ └── option.go ├── docker ├── Dockerfile ├── build.sh ├── docker-compose.yml └── docker.go ├── drawio ├── BigData.drawio ├── IM2.0.Process.drawio ├── IM2.0.drawio ├── Untitled Diagram.drawio ├── im架构.drawio ├── istio_test.drawio ├── pay.drawio ├── service_plan.drawio └── user-center.excalidraw ├── ebcdic ├── EBCDIC.txt ├── ebcdic.go └── main.go ├── encryption_algorithm ├── aes.go ├── curve25519_test.go ├── dh_test.go ├── kdf_test.go └── x3curve25519_test.go ├── err └── main.go ├── es ├── README.md ├── es_ik_test.go ├── es_test.go ├── go.mod └── go.sum ├── etcd ├── discovery │ ├── discovery.go │ ├── options.go │ └── version_balancer.go ├── etcd-grpc │ ├── api.proto │ ├── api │ │ └── api.pb.go │ ├── client_test.go │ └── server.go ├── lock │ ├── etcd.go │ ├── etcd_lock.go │ └── etcd_lock_test.go └── register │ ├── options.go │ ├── register.go │ └── register_test.go ├── filewatch └── main.go ├── flink_kafka_clickhouse ├── clickhouse.sql ├── flink.sql └── kafka.go ├── game ├── elo │ ├── elo.go │ └── elo_test.go └── match │ ├── match.go │ └── match_test.go ├── gcache ├── chace.go ├── gchace.go ├── gchace_test.go ├── lru.go └── lru_test.go ├── geo ├── mgo │ └── main.go └── redis │ └── main.go ├── gin ├── conf │ ├── mysql.json │ └── seelog.xml ├── controller │ ├── annoucement.go │ ├── base.go │ └── code.go ├── docs │ ├── docs.go │ └── swagger │ │ ├── swagger.json │ │ └── swagger.yaml ├── log │ └── other.log.27.07.2018 ├── main.go ├── model │ ├── announcement.go │ ├── code.go │ └── db.go ├── protos │ ├── annoucement.pb.go │ └── source │ │ └── annoucement.proto └── router │ └── router.go ├── gitconfig.sh ├── go-kit ├── README.md ├── v1 │ ├── main.go │ ├── v1_endpoint │ │ └── endpoint.go │ ├── v1_service │ │ ├── model.go │ │ └── service.go │ └── v1_transport │ │ └── transport.go ├── v11 │ ├── filebeat_v11.yml │ ├── logstash-sample.conf │ ├── user_agent │ │ ├── Dockerfile │ │ ├── build.sh │ │ ├── client │ │ │ ├── user_agent_client.go │ │ │ ├── user_agent_test.go │ │ │ └── user_client.go │ │ ├── main.go │ │ ├── pb │ │ │ ├── make.sh │ │ │ ├── service.pb.go │ │ │ ├── service.proto │ │ │ ├── user.pb.go │ │ │ └── user.proto │ │ └── src │ │ │ ├── endpoint.go │ │ │ ├── middleware_endpoint.go │ │ │ ├── middleware_log.go │ │ │ ├── middleware_metrics.go │ │ │ ├── middleware_tracer.go │ │ │ ├── service.go │ │ │ └── transport_server.go │ └── utils │ │ ├── hystrix.go │ │ ├── jaeger.go │ │ ├── jwt.go │ │ ├── jwt_test.go │ │ ├── log.go │ │ └── zap_log_error_handler.go ├── v2 │ ├── main.go │ ├── utils │ │ └── log.go │ ├── v2_endpoint │ │ ├── endpoint.go │ │ └── middleware.go │ ├── v2_service │ │ ├── middleware.go │ │ ├── model.go │ │ └── service.go │ └── v2_transport │ │ ├── ZapLogErrorHandler.go │ │ └── transport.go ├── v3 │ ├── main.go │ ├── utils │ │ ├── jwt.go │ │ ├── jwt_test.go │ │ └── log.go │ ├── v3_endpoint │ │ ├── endpoint.go │ │ └── middleware.go │ ├── v3_service │ │ ├── middleware.go │ │ ├── model.go │ │ └── service.go │ └── v3_transport │ │ └── transport.go ├── v4 │ ├── main.go │ ├── utils │ │ ├── jwt.go │ │ ├── jwt_test.go │ │ └── log.go │ ├── v4_endpoint │ │ ├── endpoint.go │ │ └── middleware.go │ ├── v4_service │ │ ├── middleware.go │ │ ├── model.go │ │ └── service.go │ └── v4_transport │ │ └── transport.go ├── v5 │ ├── utils │ │ ├── jwt.go │ │ ├── jwt_test.go │ │ └── log.go │ └── v5_user │ │ ├── client │ │ ├── client.go │ │ └── grpc_test.go │ │ ├── main.go │ │ ├── pb │ │ ├── make.sh │ │ ├── service.pb.go │ │ ├── service.proto │ │ ├── user.pb.go │ │ └── user.proto │ │ ├── v5_endpoint │ │ ├── endpoint.go │ │ └── middleware.go │ │ ├── v5_service │ │ ├── middleware.go │ │ └── service.go │ │ └── v5_transport │ │ ├── ZapLogErrorHandler.go │ │ └── transport_server.go ├── v6 │ ├── user_agent │ │ ├── client │ │ │ ├── user_agent_client.go │ │ │ └── user_agent_test.go │ │ ├── main.go │ │ ├── pb │ │ │ ├── make.sh │ │ │ ├── service.pb.go │ │ │ ├── service.proto │ │ │ ├── user.pb.go │ │ │ └── user.proto │ │ └── src │ │ │ ├── endpoint.go │ │ │ ├── middleware_endpoint.go │ │ │ ├── middleware_server.go │ │ │ ├── service.go │ │ │ └── transport_server.go │ └── utils │ │ ├── jwt.go │ │ ├── jwt_test.go │ │ ├── log.go │ │ └── zap_log_error_handler.go ├── v7 │ ├── user_agent │ │ ├── client │ │ │ ├── user_agent_client.go │ │ │ └── user_agent_test.go │ │ ├── main.go │ │ ├── pb │ │ │ ├── make.sh │ │ │ ├── service.pb.go │ │ │ ├── service.proto │ │ │ ├── user.pb.go │ │ │ └── user.proto │ │ └── src │ │ │ ├── endpoint.go │ │ │ ├── middleware_endpoint.go │ │ │ ├── middleware_log.go │ │ │ ├── middleware_metrics.go │ │ │ ├── service.go │ │ │ └── transport_server.go │ └── utils │ │ ├── jwt.go │ │ ├── jwt_test.go │ │ ├── log.go │ │ └── zap_log_error_handler.go ├── v8 │ ├── user_agent │ │ ├── client │ │ │ ├── user_agent_client.go │ │ │ └── user_agent_test.go │ │ ├── main.go │ │ ├── pb │ │ │ ├── make.sh │ │ │ ├── service.pb.go │ │ │ ├── service.proto │ │ │ ├── user.pb.go │ │ │ └── user.proto │ │ └── src │ │ │ ├── endpoint.go │ │ │ ├── middleware_endpoint.go │ │ │ ├── middleware_log.go │ │ │ ├── middleware_metrics.go │ │ │ ├── service.go │ │ │ └── transport_server.go │ └── utils │ │ ├── hystrix.go │ │ ├── jwt.go │ │ ├── jwt_test.go │ │ ├── log.go │ │ └── zap_log_error_handler.go └── v9 │ ├── user_agent │ ├── build.sh │ ├── client │ │ ├── user_agent_client.go │ │ └── user_agent_test.go │ ├── main.go │ ├── pb │ │ ├── make.sh │ │ ├── service.pb.go │ │ ├── service.proto │ │ ├── user.pb.go │ │ └── user.proto │ └── src │ │ ├── endpoint.go │ │ ├── middleware_endpoint.go │ │ ├── middleware_log.go │ │ ├── middleware_metrics.go │ │ ├── middleware_tracer.go │ │ ├── service.go │ │ └── transport_server.go │ └── utils │ ├── hystrix.go │ ├── jaeger.go │ ├── jwt.go │ ├── jwt_test.go │ ├── log.go │ └── zap_log_error_handler.go ├── go-lua └── main.go ├── go.mod ├── go.sum ├── go_push ├── gateway │ ├── push_job.go │ ├── room.go │ ├── room_manage.go │ ├── ws_conn.go │ ├── ws_handle.go │ └── ws_server.go ├── logic │ ├── http_handle.go │ └── http_server.go └── main.go ├── gocmp └── cmp_test.go ├── goconvey ├── coverage.sh ├── goconvey.go ├── goconvey_test.go ├── goconvey_v1.go └── goconvey_v1_test.go ├── goquery └── main.go ├── gossip └── gossip_test.go ├── grpc ├── bidirectional_streaming_rpc │ ├── howie_test.go │ ├── main.go │ └── proto │ │ ├── howie.pb.go │ │ ├── howie.proto │ │ └── make.sh ├── protoc-gen-hw │ ├── examples │ │ └── greeter │ │ │ └── greeter.proto │ ├── generator │ │ └── generator.go │ ├── main.go │ └── plugin │ │ └── hw │ │ └── hw.go ├── server_side_streaming_rpc │ ├── howie_test.go │ ├── main.go │ └── proto │ │ ├── howie.pb.go │ │ └── howie.proto └── simple_rpc │ ├── howie_test.go │ ├── main.go │ └── proto │ └── howie.pb.go ├── hbase ├── README.md └── hbase_test.go ├── hconf ├── README.md ├── hconf.go ├── hconf.yaml ├── hconf_test.go └── options.go ├── hconfig ├── README.md ├── apollo │ ├── config.go │ ├── config_test.go │ ├── options.go │ └── watcher.go ├── etcd │ ├── config.go │ ├── config_test.go │ ├── options.go │ └── watcher.go ├── h_val.go ├── hconf │ └── hconfig.go ├── hconfig.go ├── hconfig_test.go ├── kubernetes │ ├── config.go │ ├── config_test.go │ ├── k8s.go │ ├── options.go │ └── watcher.go └── options.go ├── hevent ├── event.go └── event_test.go ├── hlb-grpc ├── discovery │ ├── customize_balancer.go │ ├── discovery.go │ └── options.go ├── example │ ├── api.proto │ ├── api │ │ └── api.pb.go │ ├── client_test.go │ └── server.go └── register │ ├── options.go │ ├── register.go │ └── register_test.go ├── hlog ├── README.md ├── example │ └── main.go ├── options.go ├── zap.go └── zap_test.go ├── hystrix └── hystrix_test.go ├── ini ├── main.go └── my.ini ├── interface ├── f_test.go ├── main.go ├── middleware │ ├── middleware.go │ ├── middleware_server.go │ └── middleware_test.go └── src │ ├── Agent.go │ └── Howie.go ├── istio ├── README.md ├── api │ ├── api.pb.go │ ├── api.proto │ └── cmd.sh ├── gateway │ ├── Dockerfile │ ├── README.md │ ├── build.sh │ ├── gateway.go │ ├── ws_conn.go │ └── ws_handle.go ├── kube │ ├── gateway.yaml │ ├── logic.yaml │ ├── net-gateway.yaml │ ├── net-logic.yaml │ ├── net-redis.yaml │ ├── nfs-client.yaml │ ├── nfs-pvc.yaml │ ├── nfs-rabc.yaml │ ├── nfs-sc.yaml │ └── nfs-test.yaml ├── logic_v1 │ ├── Dockerfile │ ├── build.sh │ └── logicV1.go ├── logic_v2 │ ├── Dockerfile │ ├── build.sh │ └── logicV2.go └── logic_v3 │ ├── Dockerfile │ ├── build.sh │ ├── logicV3.go │ └── redis.go ├── jaeger ├── jaeger_test.go └── main.go ├── job_worker_mode ├── debug_test.go ├── dispatcher.go ├── goods.go └── worker.go ├── jwt ├── conf │ ├── rsa_private_key.pem │ └── rsa_public_key.pem ├── controller │ ├── base.go │ └── token.go └── main.go ├── k8s-api ├── k8s.go ├── k8s_configMap_test.go ├── k8s_pod_test.go └── pod.yaml ├── k8s ├── Dockerfile ├── app.yml ├── app_service.yml ├── ci-cd │ ├── .gitlab-ci.yml │ ├── Dockerfile │ ├── README.md │ ├── certs.sh │ └── main.go ├── main.go ├── nginx.yml └── nginx_service.yml ├── kafka ├── kafka_test.go ├── main.go └── offset_test.go ├── makefile ├── Makefile ├── README.md └── main.go ├── micro_agent ├── README.md ├── base │ ├── base.go │ ├── config │ │ ├── config.go │ │ ├── mysql.go │ │ ├── server.go │ │ └── tool.go │ ├── db │ │ ├── db.go │ │ └── mysql.go │ └── tool │ │ ├── log.go │ │ └── tool.go ├── conf │ ├── mysql.ini │ ├── tool.ini │ └── user_agent.ini ├── handler │ ├── hander.go │ └── user.go ├── main.go ├── model │ ├── model.go │ └── user │ │ ├── user.go │ │ └── user_info.go ├── proto │ └── user │ │ ├── make.sh │ │ ├── user.micro.go │ │ ├── user.pb.go │ │ └── user.proto └── resource │ └── 0190627140759.png ├── micro_v2 ├── client │ └── main.go ├── config │ └── main.go ├── ecode │ ├── common_ecode.go │ ├── ecode.go │ └── micro_wrapper.go ├── etcd_lock_test.go ├── go.mod ├── go.sum ├── make.sh ├── server │ └── main.go ├── test.pb.go ├── test.pb.micro.go └── test.proto ├── minio ├── main.go ├── minio_test.go ├── minio_thumbnail │ ├── cli.go │ ├── main.go │ └── thumbnail.go └── old │ ├── main.go │ └── minio_test.go ├── mongodb ├── mgo.v2 │ └── main.go └── mongo-go-driver │ └── main.go ├── mysql └── main.go ├── network ├── addr.go ├── ip.go └── ip_test.go ├── nsq ├── howie_test.go └── main.go ├── other ├── 00_ff_test.go ├── README.md ├── binaryFind_test.go ├── ip_test.go ├── json_test.go ├── master_node_test.go ├── qsort_test.go ├── t_test.go ├── tool_test.go └── trie_test.go ├── prometheus ├── howie_test.go └── server.go ├── proxy └── proxy_http │ ├── proxy.go │ └── server │ └── service.go ├── push ├── handler │ ├── msg.go │ ├── server.go │ ├── tcp_handler.go │ └── ws_handler.go ├── main.go └── push_test.go ├── quic ├── ca.pem ├── cert.pem ├── generate_key.sh ├── priv.key ├── quic_client.go └── quic_server.go ├── redis ├── bitmap_filter │ ├── bitmap.go │ └── bitmap_test.go ├── bloom_filter │ └── bloom_filter.go ├── lock │ ├── lock.go │ ├── lock_server.go │ └── lock_test.go ├── pipeline │ └── main.go └── subscription │ └── main.go ├── reflect └── main.go ├── req_limit ├── howie_test.go ├── main.go └── uber_ratelimit_test.go ├── rocketmq ├── README.md ├── go.mod ├── go.sum ├── mq_test.go └── transaction.go ├── rocksdb ├── Dockerfile └── rocksdb.md ├── rpc ├── main.go └── rpc_test.go ├── service_load_balancing └── fisher_yates_test.go ├── slog └── main.go ├── snow_flake ├── snow_flake.go └── snow_flake_52.go ├── sql-redis └── main.go ├── syncPool └── main.go ├── tcp ├── howie_test.go ├── main.go └── network │ ├── tcp_conn.go │ └── tcp_server.go ├── timewheel ├── timewheel.go └── timewheel_test.go ├── timezonefinder ├── country_to_continent_mapping.go ├── finder.go ├── finder_test.go ├── zone.go └── zone.tab ├── tool ├── binary_conversion │ ├── 10to36.go │ ├── 10to62.go │ ├── 10to76.go │ └── binary.go └── decimal │ └── decimal.go ├── websocket ├── cmd │ ├── client │ │ └── ws_client_test.go │ └── main.go ├── gateway │ ├── msg │ │ ├── errors.go │ │ ├── msg.go │ │ └── msg_test.go │ └── ws │ │ ├── ws_center.go │ │ ├── ws_conn.go │ │ ├── ws_handle.go │ │ └── ws_server.go └── pb │ ├── msg.pb.go │ └── msg.proto └── wire ├── main.go ├── test.go ├── wire.go └── wire_gen.go /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hwholiday/learning_tools/71e1320fd3e105ddfde80cc0a88e70d7ad7a41cd/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Go template 3 | # Binaries for programs and plugins 4 | *.exe 5 | *.exe~ 6 | *.dll 7 | *.so 8 | *.dylib 9 | 10 | # Test binary, build with `go test -c` 11 | *.test 12 | 13 | # Output of the go coverage tool, specifically when used with LiteIDE 14 | *.out 15 | /.idea -------------------------------------------------------------------------------- /LRU/lru_test.go: -------------------------------------------------------------------------------- 1 | package LRU 2 | 3 | import "testing" 4 | 5 | func TestNewList(t *testing.T) { 6 | callBack := func(key interface{}, value interface{}) { 7 | t.Log("del", key, value) 8 | } 9 | l := NewLru(2, callBack) 10 | t.Log(l.Add("1", "1")) 11 | t.Log(l.Add("2", "2")) 12 | for _, v := range l.GetAll() { 13 | t.Log("Key", v.Key, "Val", v.Val) 14 | } 15 | t.Log(l.Add("3", "3")) 16 | t.Log(l.Add("4", "4")) 17 | for _, v := range l.GetAll() { 18 | t.Log("Key", v.Key, "Val", v.Val) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /NATS_streaming/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | //nats-streaming-server --store file -dir /home/ghost/data/nats 4 | import ( 5 | "fmt" 6 | "github.com/nats-io/stan.go" 7 | "log" 8 | "time" 9 | ) 10 | 11 | func main() { 12 | var clusterId string = "test-cluster" 13 | var clientId string = "test-client" 14 | sc, err := stan.Connect(clusterId, clientId, stan.NatsURL("nats://localhost:4222")) 15 | if err != nil { 16 | log.Fatal(err) 17 | return 18 | } 19 | go func() { 20 | for { 21 | time.Sleep(time.Second) 22 | sc.Publish("foo", []byte("nast test")) 23 | } 24 | }() 25 | sub, _ := sc.Subscribe("foo", func(m *stan.Msg) { 26 | fmt.Printf("Received a message: %s\n", string(m.Data)) 27 | }) 28 | defer sub.Unsubscribe() 29 | defer sc.Close() 30 | signalChan := make(chan int) 31 | <-signalChan 32 | 33 | } 34 | -------------------------------------------------------------------------------- /active_object/active_object.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | const ( 9 | Add = 1 10 | Lessen = 2 11 | ) 12 | 13 | type Service struct { 14 | queue chan int 15 | val int 16 | } 17 | 18 | func NewService(buffer int) *Service { 19 | info := &Service{queue: make(chan int, buffer)} 20 | go info.schedule() 21 | return info 22 | } 23 | 24 | func (s *Service) schedule() { 25 | for { 26 | select { 27 | case i := <-s.queue: 28 | if i == Add { 29 | fmt.Println("s.val++") 30 | s.val++ 31 | } else if i == Lessen { 32 | fmt.Println("s.val--") 33 | s.val-- 34 | } 35 | case <-time.After(time.Second * 5): 36 | fmt.Println("5秒没有写入") 37 | } 38 | } 39 | } 40 | 41 | func (s *Service) Add() { 42 | fmt.Println("s.queue <- Add") 43 | s.queue <- Add 44 | } 45 | 46 | func (s *Service) Lessen() { 47 | fmt.Println("s.queue <- Lessen") 48 | s.queue <- Lessen 49 | } 50 | -------------------------------------------------------------------------------- /active_object/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | //Go并发设计模式之 Active Object 9 | //https://colobu.com/2019/07/02/concurrency-design-patterns-active-object/ 10 | func main() { 11 | info := NewService(1) 12 | for i := 0; i < 20; i++ { 13 | info.Add() 14 | fmt.Println(info.val) //不是同步返回值 15 | //info.Lessen() 16 | //fmt.Println(info.val) 17 | } 18 | fmt.Println(info.val) 19 | time.Sleep(time.Hour) 20 | } 21 | -------------------------------------------------------------------------------- /all_packaged_library/base/base.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | import ( 4 | "file_storage/base/config" 5 | "file_storage/base/db" 6 | "file_storage/base/tool" 7 | ) 8 | 9 | //配置文件的目录 10 | func Init(path string) { 11 | config.Init(path) 12 | tool.Init() 13 | db.Init() 14 | } 15 | -------------------------------------------------------------------------------- /all_packaged_library/base/config/minio.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | type minConfig interface { 4 | GetPath() string 5 | GetAccessKeyId() string 6 | GetSecretAccessKey() string 7 | } 8 | 9 | type defaultMinioConfig struct { 10 | Path string `ini:"path"` 11 | AccessKeyId string `ini:"access_key_id"` 12 | SecretAccessKey string `ini:"secret_access_key"` 13 | } 14 | 15 | func (m defaultMinioConfig) GetPath() string { 16 | return m.Path 17 | } 18 | 19 | func (m defaultMinioConfig) GetAccessKeyId() string { 20 | return m.AccessKeyId 21 | } 22 | 23 | func (m defaultMinioConfig) GetSecretAccessKey() string { 24 | return m.SecretAccessKey 25 | } 26 | -------------------------------------------------------------------------------- /all_packaged_library/base/config/mongodb.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | type mgConfig interface { 4 | GetUrl() string 5 | GetName() string 6 | GetPass() string 7 | } 8 | 9 | type defaultMgoConfig struct { 10 | Url string `ini:"url"` 11 | Name string `ini:"name"` 12 | Pass string `ini:"pass"` 13 | } 14 | 15 | func (m defaultMgoConfig) GetUrl() string { 16 | return m.Url 17 | } 18 | func (m defaultMgoConfig) GetName() string { 19 | return m.Name 20 | } 21 | func (m defaultMgoConfig) GetPass() string { 22 | return m.Pass 23 | } 24 | -------------------------------------------------------------------------------- /all_packaged_library/base/config/mysql.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | type msqlConfig interface { 4 | GetIp() string 5 | GetPort() int 6 | GetUser() string 7 | GetPwd() string 8 | GetDbName() string 9 | GetPoolSize() int 10 | } 11 | 12 | type defaultMysqlConfig struct { 13 | Ip string `ini:"ip"` 14 | Port int `ini:"port"` 15 | User string `ini:"user"` 16 | Pwd string `ini:"pwd"` 17 | DbName string `ini:"dbName"` 18 | PoolSize int `ini:"poolSize"` 19 | } 20 | 21 | func (m defaultMysqlConfig) GetIp() string { 22 | return m.Ip 23 | } 24 | 25 | func (m defaultMysqlConfig) GetPort() int { 26 | return m.Port 27 | } 28 | 29 | func (m defaultMysqlConfig) GetUser() string { 30 | return m.User 31 | } 32 | 33 | func (m defaultMysqlConfig) GetPwd() string { 34 | return m.Pwd 35 | } 36 | func (m defaultMysqlConfig) GetDbName() string { 37 | return m.DbName 38 | } 39 | func (m defaultMysqlConfig) GetPoolSize() int { 40 | return m.PoolSize 41 | } 42 | -------------------------------------------------------------------------------- /all_packaged_library/base/config/redis.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | type rdsConfig interface { 4 | GetIP() string 5 | GetPort() string 6 | GetPass() string 7 | GetMaxOpen() int 8 | } 9 | 10 | type defaultRedisConfig struct { 11 | IP string `ini:"ip"` 12 | Port string `ini:"port"` 13 | Pass string `ini:"pass"` 14 | MaxOpen int `ini:"max_open"` 15 | } 16 | 17 | func (m defaultRedisConfig) GetIP() string { 18 | return m.IP 19 | } 20 | func (m defaultRedisConfig) GetPort() string { 21 | return m.Port 22 | } 23 | func (m defaultRedisConfig) GetPass() string { 24 | return m.Pass 25 | } 26 | func (m defaultRedisConfig) GetMaxOpen() int { 27 | return m.MaxOpen 28 | } 29 | -------------------------------------------------------------------------------- /all_packaged_library/base/config/server.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | type serversConfig interface { 4 | GetEtcd() string 5 | GetName() string 6 | GetAddr() string 7 | } 8 | 9 | type defaultServerConfig struct { 10 | Etcd string `ini:"etcd"` 11 | Name string `ini:"name"` 12 | Addr string `ini:"addr"` 13 | } 14 | 15 | func (m defaultServerConfig) GetEtcd() string { 16 | return m.Etcd 17 | } 18 | 19 | func (m defaultServerConfig) GetName() string { 20 | return m.Name 21 | } 22 | func (m defaultServerConfig) GetAddr() string { 23 | return m.Addr 24 | } 25 | -------------------------------------------------------------------------------- /all_packaged_library/base/db.ini: -------------------------------------------------------------------------------- 1 | [redis] 2 | ip = 127.0.0.1 3 | port = 6379 4 | pass = 5 | max_open = 100 6 | [mongodb] 7 | url = mongodb://127.0.0.1:27017 8 | name = 9 | pass = 10 | [minio] 11 | # s3地址 s3.amazonaws.com 12 | path = 127.0.0.1:9000 13 | access_key_id = 123123 14 | secret_access_key = 123123123/WNXtw6PJob 15 | [mysql] 16 | ip = "192.168.2.1" 17 | port = 3306 18 | user = "root" 19 | pwd = "123123" 20 | dbName = "test" 21 | poolSize = 100 -------------------------------------------------------------------------------- /all_packaged_library/base/db/db.go: -------------------------------------------------------------------------------- 1 | package db 2 | 3 | import ( 4 | "github.com/go-redis/redis" 5 | "github.com/go-xorm/xorm" 6 | "github.com/minio/minio-go" 7 | "go.mongodb.org/mongo-driver/mongo" 8 | "sync" 9 | ) 10 | 11 | var ( 12 | err error 13 | redisDb *redis.Client 14 | minioClient *minio.Client 15 | mgo *mongo.Client 16 | mysqlEngine *xorm.Engine 17 | m sync.Mutex 18 | ) 19 | 20 | func Init() { 21 | m.Lock() 22 | defer m.Unlock() 23 | initRedis() 24 | initMongoDb() 25 | initMinio() 26 | initMysql() 27 | } 28 | 29 | func GetRedisDb() *redis.Client { 30 | return redisDb 31 | } 32 | 33 | func CloseRedisDb() { 34 | closeRedis() 35 | } 36 | 37 | func GetMgoDb() *mongo.Client { 38 | return mgo 39 | } 40 | 41 | func GetMinioClient() *minio.Client { 42 | return minioClient 43 | } 44 | 45 | func GetMysqlDb() *xorm.Engine { 46 | return mysqlEngine 47 | } 48 | 49 | func CloseMysqlDb() { 50 | CloseMysqlConnection() 51 | } 52 | -------------------------------------------------------------------------------- /all_packaged_library/base/db/minio.go: -------------------------------------------------------------------------------- 1 | package db 2 | 3 | import ( 4 | "file_storage/base/config" 5 | "file_storage/base/tool" 6 | "github.com/minio/minio-go" 7 | ) 8 | 9 | func initMinio() { 10 | var secure bool 11 | if config.GetMinioConfig().GetPath() == "s3.amazonaws.com" { 12 | secure = true 13 | } 14 | if minioClient, err = minio.New(config.GetMinioConfig().GetPath(), config.GetMinioConfig().GetAccessKeyId(), config.GetMinioConfig().GetSecretAccessKey(), secure); err != nil { 15 | panic(err) 16 | } 17 | tool.GetLogger().Debug("minio success : " + config.GetMinioConfig().GetPath()) 18 | /*for i:=1;i<=100;i++{ 19 | var bucketName bytes.Buffer 20 | bucketName.WriteString("storage") 21 | bucketName.WriteString("-") 22 | bucketName.WriteString(strconv.Itoa(int(i))) 23 | fmt.Println(minioClient.MakeBucket(bucketName.String(),"")) 24 | }*/ 25 | } 26 | -------------------------------------------------------------------------------- /all_packaged_library/base/db/mongodb.go: -------------------------------------------------------------------------------- 1 | package db 2 | 3 | import ( 4 | "context" 5 | "file_storage/base/config" 6 | "file_storage/base/tool" 7 | "go.mongodb.org/mongo-driver/mongo" 8 | "go.mongodb.org/mongo-driver/mongo/options" 9 | "time" 10 | ) 11 | 12 | func initMongoDb() { 13 | //链接mongo服务 14 | opt := options.Client().ApplyURI(config.GetMgoConfig().GetUrl()) 15 | opt.SetLocalThreshold(3 * time.Second) //只使用与mongo操作耗时小于3秒的 16 | if config.GetMgoConfig().GetName() != "" && config.GetMgoConfig().GetPass() != "" { 17 | opt.SetAuth(options.Credential{ 18 | Username: config.GetMgoConfig().GetName(), 19 | Password: config.GetMgoConfig().GetPass(), 20 | }) 21 | } 22 | opt.SetMaxConnIdleTime(5 * time.Second) //指定连接可以保持空闲的最大毫秒数 23 | opt.SetMaxPoolSize(200) //使用最大的连接数 24 | if mgo, err = mongo.Connect(context.TODO(), opt); err != nil { 25 | panic(err) 26 | } 27 | tool.GetLogger().Debug("mgo success : " + config.GetMgoConfig().GetUrl()) 28 | 29 | } 30 | -------------------------------------------------------------------------------- /all_packaged_library/base/db/mysql.go: -------------------------------------------------------------------------------- 1 | package db 2 | 3 | import ( 4 | "fmt" 5 | _ "github.com/go-sql-driver/mysql" 6 | "github.com/go-xorm/xorm" 7 | "go.uber.org/zap" 8 | "live/base/config" 9 | "live/base/tool" 10 | "os" 11 | ) 12 | 13 | //mysql连接池 14 | func initMysql() { 15 | var err error 16 | sql := fmt.Sprintf("%s:%s@(%s:%d)/%s", config.GetMysqlConfig().GetUser(), config.GetMysqlConfig().GetPwd(), 17 | config.GetMysqlConfig().GetIp(), config.GetMysqlConfig().GetPort(), config.GetMysqlConfig().GetDbName()) 18 | tool.GetLogger().Debug("[initMysql] " + sql) 19 | mysqlEngine, err = xorm.NewEngine("mysql", sql) 20 | if err != nil { 21 | tool.GetLogger().Error("[initMysql] "+sql, zap.Error(err)) 22 | os.Exit(0) 23 | } 24 | mysqlEngine.SetMaxOpenConns(config.GetMysqlConfig().GetPoolSize()) 25 | mysqlEngine.SetMaxIdleConns(config.GetMysqlConfig().GetPoolSize()) 26 | if err = mysqlEngine.Ping(); err != nil { 27 | panic(err) 28 | } 29 | } 30 | 31 | func CloseMysqlConnection() { 32 | _ = mysqlEngine.Close() 33 | } 34 | -------------------------------------------------------------------------------- /all_packaged_library/base/db/redis.go: -------------------------------------------------------------------------------- 1 | package db 2 | 3 | import ( 4 | "file_storage/base/config" 5 | "file_storage/base/tool" 6 | "fmt" 7 | "github.com/go-redis/redis" 8 | "go.uber.org/zap" 9 | "time" 10 | ) 11 | 12 | func initRedis() { 13 | 14 | redisDb = redis.NewClient( 15 | &redis.Options{ 16 | Addr: fmt.Sprintf("%s:%s", config.GetRedisConfig().GetIP(), config.GetRedisConfig().GetPort()), 17 | DialTimeout: 10 * time.Second, 18 | ReadTimeout: 30 * time.Second, 19 | WriteTimeout: 30 * time.Second, 20 | Password: config.GetRedisConfig().GetPass(), 21 | PoolSize: config.GetRedisConfig().GetMaxOpen(), 22 | }, 23 | ) 24 | err = redisDb.Ping().Err() 25 | if nil != err { 26 | tool.GetLogger().Error("ping redis err:", zap.Error(err)) 27 | panic(err) 28 | } 29 | tool.GetLogger().Debug("redis success : " + fmt.Sprintf("%s:%s", config.GetRedisConfig().GetIP(), config.GetRedisConfig().GetPort())) 30 | 31 | } 32 | 33 | func closeRedis() { 34 | if redisDb != nil { 35 | _ = redisDb.Close() 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /all_packaged_library/base/tool.ini: -------------------------------------------------------------------------------- 1 | [server] 2 | etcd = http://192.168.2.118:2379 3 | name = bat.file.storage 4 | addr = 127.0.0.1:8080 5 | [zap] 6 | #appName 日志的前缀 7 | appName = file_storage 8 | #development 是否是生产模式 9 | development = true 10 | #logFileDir 日志文件存放目录 11 | logFileDir = logs 12 | #maxSize 日志文件大小最大值 13 | maxSize = 50 14 | #maxBackups 最大保存文件数 15 | maxBackups = 200 16 | #maxAge 最大保存天数 17 | maxAge = 10 18 | #dc 服务器编号(1~1024) 19 | dc = 1 20 | -------------------------------------------------------------------------------- /all_packaged_library/base/tool/redis_lock.go: -------------------------------------------------------------------------------- 1 | package tool 2 | 3 | import ( 4 | "github.com/go-redis/redis" 5 | "time" 6 | ) 7 | 8 | type RedisLock struct { 9 | conn *redis.Client 10 | timeout time.Duration 11 | key string 12 | val string 13 | } 14 | 15 | func NewRedisLock(conn *redis.Client, key, val string, timeout time.Duration) *RedisLock { 16 | return &RedisLock{conn: conn, timeout: timeout, key: key, val: val} 17 | } 18 | 19 | //return true ===> Get the lock successfully 20 | func (lock *RedisLock) TryLock() (bool, error) { 21 | return lock.conn.SetNX(lock.key, lock.val, lock.timeout).Result() 22 | } 23 | 24 | func (lock *RedisLock) UnLock() error { 25 | return lock.conn.Del(lock.key).Err() 26 | } 27 | 28 | func (lock *RedisLock) GetLockKey() string { 29 | return lock.key 30 | } 31 | 32 | func (lock *RedisLock) GetLockVal() string { 33 | return lock.val 34 | } 35 | -------------------------------------------------------------------------------- /all_packaged_library/base/tool/signal.go: -------------------------------------------------------------------------------- 1 | package tool 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "os/signal" 7 | "syscall" 8 | ) 9 | 10 | func QuitSignal(quitFunc func()) { 11 | c := make(chan os.Signal, 1) 12 | signal.Notify(c, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT) 13 | fmt.Printf("server start success pid:%d\n", os.Getpid()) 14 | for s := range c { 15 | switch s { 16 | case syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT: 17 | quitFunc() 18 | return 19 | default: 20 | return 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /all_packaged_library/base/tool/tool.go: -------------------------------------------------------------------------------- 1 | package tool 2 | 3 | import ( 4 | "github.com/hwholiday/learning_tools/all_packaged_library/base/config" 5 | "sync" 6 | ) 7 | 8 | var ( 9 | one sync.Once 10 | err error 11 | ) 12 | 13 | func Init() { 14 | one.Do(func() { 15 | initLogger(getLoggerOptions()) 16 | //NewWorker ID 填入 分布式的服务唯一ID从1到1024 17 | if err = NewWorker(config.GetToolLogConfig().GetDcId()); err != nil { 18 | panic(err) 19 | } 20 | }) 21 | } 22 | func getLoggerOptions() *Options { 23 | op := &Options{} 24 | op.Development = config.GetToolLogConfig().GetDevelopment() 25 | op.LogFileDir = config.GetToolLogConfig().GetLogFileDir() 26 | op.AppName = config.GetToolLogConfig().GetAppName() 27 | op.MaxSize = config.GetToolLogConfig().GetMaxSize() 28 | op.MaxBackups = config.GetToolLogConfig().GetMaxBackups() 29 | op.MaxAge = config.GetToolLogConfig().GetMaxAge() 30 | return op 31 | } 32 | -------------------------------------------------------------------------------- /all_packaged_library/base/tool/utils.go: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: howie 3 | * @Date: 2019-07-02 11:38:19 4 | * @Last Modified by: holiday 5 | * @Last Modified time: 2019-07-02 13:19:17 6 | */ 7 | package tool 8 | 9 | import ( 10 | "time" 11 | ) 12 | 13 | func GetTime() int64 { 14 | return time.Now().Unix() 15 | 16 | } 17 | -------------------------------------------------------------------------------- /all_packaged_library/logtool/log_test.go: -------------------------------------------------------------------------------- 1 | package logtool 2 | 3 | import ( 4 | "fmt" 5 | "go.uber.org/zap" 6 | "testing" 7 | "time" 8 | ) 9 | 10 | func TestInitZapV2Logger(t *testing.T) { 11 | lg := NewLogger(SetAppName("test_app"), SetDevelopment(true), SetLevel(zap.DebugLevel), SetErrorFileName("error_e_e_e_e.log")) 12 | for i := 0; i < 10; i++ { 13 | time.Sleep(time.Second) 14 | lg.Debug(fmt.Sprint("debug log ", 1), zap.Int("line", 47)) 15 | lg.Info(fmt.Sprint("Info log ", 2), zap.Any("level", "1231231231")) 16 | lg.Warn(fmt.Sprint("warn log ", 3), zap.String("level", `{"a":"4","b":"5"}`)) 17 | lg.Error(fmt.Sprint("err log ", 4), zap.String("level", `{"a":"7","b":"8"}`)) 18 | 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /all_packaged_library/perf/perf.go: -------------------------------------------------------------------------------- 1 | package perf 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "net/http/pprof" 7 | ) 8 | 9 | // StartPprof start http pprof 10 | func StartPprof(addrs []string) { 11 | pprofServeMux := http.NewServeMux() 12 | pprofServeMux.HandleFunc("/debug/pprof/symbol", pprof.Symbol) 13 | pprofServeMux.HandleFunc("/debug/pprof/profile", pprof.Profile) 14 | pprofServeMux.HandleFunc("/debug/pprof/", pprof.Index) 15 | pprofServeMux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline) 16 | for _, addr := range addrs { 17 | go func() { 18 | if err := http.ListenAndServe(addr, pprofServeMux); err != nil { 19 | fmt.Printf("http.ListenAndServe(\"%s\", pprofServeMux) error(%v)", addr, err) 20 | panic(err) 21 | } 22 | }() 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /all_packaged_library/perf/perf_test.go: -------------------------------------------------------------------------------- 1 | package perf 2 | 3 | import "testing" 4 | 5 | func TestStartPprof(t *testing.T) { 6 | StartPprof([]string{"127.0.0.1:8077"}) 7 | select {} 8 | } 9 | -------------------------------------------------------------------------------- /all_packaged_library/push/apple_pushkit/pushkit_test.go: -------------------------------------------------------------------------------- 1 | package apple_pushkit 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestInitPushKit(t *testing.T) { 9 | push, err := InitPushKit("./131231P.p12", "pwd", true) 10 | if err != nil { 11 | fmt.Println(err) 12 | } 13 | fmt.Println(push.Push("123123", []byte(`{"newsid":{"content":"test",},"badge":{"badge":"0"}}`))) 14 | } 15 | -------------------------------------------------------------------------------- /all_packaged_library/push/huawei/huawei_test.go: -------------------------------------------------------------------------------- 1 | package huawei 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | "time" 7 | ) 8 | 9 | func TestHuaweiPush_GetToken(t *testing.T) { 10 | push := NewHuaweiPush("https://login.cloud.huawei.com/oauth2/v2/token", "100358845", "bee1d8f704b1bc278bea7f5427cb0f8a", "https://api.push.hicloud.com/pushsend.do", true) 11 | var in ReqPush 12 | in.DeviceTokenList = []string{"0862791036717594300002894200CN01"} 13 | in.Ver = "1" 14 | in.NspTs = "1545113076" 15 | in.Payload = `{"hps":{"msg":{"type":1,"body":{"key":"value"}}}} ` 16 | for { 17 | time.Sleep(time.Second * 3) 18 | //判断ResPush中的code是不是等于80000000可以测试是否成功 19 | //{"requestId":"154536200334112580200","msg":"Success","code":"80000000"} 20 | fmt.Println(push.Push(&in)) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /all_packaged_library/quit/signal.go: -------------------------------------------------------------------------------- 1 | package quit 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "os/signal" 7 | "syscall" 8 | ) 9 | 10 | //syscall.SIGQUIT 用户发送QUIT字符(Ctrl+/)触发 11 | //syscall.SIGTERM 结束程序(可以被捕获、阻塞或忽略) 12 | //syscall.SIGINT 用户发送INTR字符(Ctrl+C)触发 13 | func QuitSignal(quitFunc func()) { 14 | c := make(chan os.Signal, 1) 15 | signal.Notify(c, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT) 16 | fmt.Printf("server start success pid:%d\n", os.Getpid()) 17 | for s := range c { 18 | switch s { 19 | case syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT: 20 | quitFunc() 21 | return 22 | default: 23 | return 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /container/heap/heap.go: -------------------------------------------------------------------------------- 1 | package heap 2 | 3 | type Item struct { 4 | data interface{} 5 | ref int //优先级 6 | index int //在堆里面的索引 7 | } 8 | type Queue []*Item 9 | 10 | func (m Queue) Len() int { 11 | return len(m) 12 | } 13 | 14 | func (m Queue) Less(i, j int) bool { 15 | return m[i].ref > m[j].ref 16 | } 17 | 18 | func (m Queue) Swap(i, j int) { 19 | m[i], m[j] = m[j], m[i] 20 | m[j].index = j 21 | m[i].index = i 22 | //位置交换把对应的索引交换 23 | } 24 | 25 | func (m *Queue) Push(d interface{}) { 26 | d.(*Item).index = len(*m) 27 | *m = append(*m, d.(*Item)) 28 | } 29 | 30 | func (m *Queue) Pop() interface{} { 31 | //抛出后面的一个数据 32 | l := len(*m) 33 | s := (*m)[l-1] 34 | s.index = -1 35 | *m = (*m)[:l-1] 36 | return s 37 | } 38 | -------------------------------------------------------------------------------- /container/heap/heap_test.go: -------------------------------------------------------------------------------- 1 | package heap 2 | 3 | import ( 4 | "container/heap" 5 | "testing" 6 | ) 7 | 8 | func TestHeap(t *testing.T) { 9 | queue := make(Queue, 10) 10 | for i := 0; i < 10; i++ { 11 | item := &Item{ 12 | data: i + 1, 13 | ref: i + 1, 14 | index: i, 15 | } 16 | queue[i] = item 17 | } 18 | heap.Init(&queue) 19 | item := Item{ 20 | data: 8, 21 | ref: 1, 22 | } 23 | heap.Push(&queue, &item) 24 | heap.Fix(&queue, 2) 25 | for queue.Len() > 0 { 26 | item := heap.Pop(&queue).(*Item) 27 | t.Log("index", item.index, "ref", item.ref, "val", item.data) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /context/go_ctx.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "time" 7 | ) 8 | 9 | func main() { 10 | ctx, cancel := context.WithTimeout(context.Background(), time.Second*4) 11 | defer cancel() 12 | go fmt.Println(doFuncSuccess(ctx)) 13 | go fmt.Println(doFuncFail(ctx)) 14 | time.Sleep(time.Second * 6) 15 | fmt.Println("doFuncFail") 16 | go fmt.Println(doFuncFail(ctx)) 17 | time.Sleep(time.Second * 2) 18 | } 19 | 20 | func doFuncSuccess(ctx context.Context) string { 21 | select { 22 | case <-ctx.Done(): 23 | return ctx.Err().Error() 24 | default: 25 | } 26 | time.Sleep(time.Second * 3) 27 | select { 28 | case <-ctx.Done(): 29 | return ctx.Err().Error() 30 | default: 31 | } 32 | return "success" 33 | } 34 | 35 | func doFuncFail(ctx context.Context) string { 36 | select { 37 | case <-ctx.Done(): 38 | return ctx.Err().Error() 39 | default: 40 | } 41 | 42 | time.Sleep(time.Second * 5) 43 | 44 | select { 45 | case <-ctx.Done(): 46 | return ctx.Err().Error() 47 | default: 48 | } 49 | return "fail" 50 | } 51 | -------------------------------------------------------------------------------- /ddd-auth2-example/adpter/http/routers/middleware.go: -------------------------------------------------------------------------------- 1 | package routers 2 | 3 | import ( 4 | "github.com/gin-contrib/cors" 5 | "github.com/gin-gonic/gin" 6 | ) 7 | 8 | func SetCorsRouters(r *gin.Engine) { 9 | r.Use(cors.New(cors.Config{ 10 | AllowAllOrigins: true, 11 | AllowMethods: []string{"*"}, 12 | AllowHeaders: []string{"Origin", "Authorization", "Content-Type", "lang", "token", "Access-Control-Allow-Origin"}, 13 | ExposeHeaders: []string{"Content-Length", "Access-Control-Allow-Origin"}, 14 | AllowCredentials: true, 15 | })) 16 | } 17 | -------------------------------------------------------------------------------- /ddd-auth2-example/adpter/http/routers/routers.go: -------------------------------------------------------------------------------- 1 | package routers 2 | 3 | import ( 4 | //"github.com/gin-contrib/pprof" 5 | "github.com/gin-gonic/gin" 6 | "github.com/hwholiday/learning_tools/ddd-auth2-example/adpter/http/auth_handles" 7 | ) 8 | 9 | func SetRouters(r *gin.Engine, h *auth_handles.Handles) { 10 | SetCorsRouters(r) 11 | r.GET("/oauth2/authorize", h.CreateCodeOpenId) //获取code 12 | r.GET("/oauth2/access_token", h.CreateToken) //通过code换取网页授权access_token 13 | r.GET("/oauth2/refresh_token", h.RefreshAccessToken) //刷新access_token 14 | r.GET("/oauth2/userinfo", h.UserInfo) //拉取用户信息(需scope为 snsapi_userinfo) 15 | r.GET("/oauth2/auth", h.CheckAccessToken) //检验授权凭证(access_token)是否有效 16 | } 17 | -------------------------------------------------------------------------------- /ddd-auth2-example/cmd/app.yaml: -------------------------------------------------------------------------------- 1 | netConf: 2 | name: app 3 | serverAddr: 0.0.0.0:8888 4 | readTimeout: 10 5 | writeTimeout: 10 6 | redis: 7 | poolSize: 20 8 | addr: 9 | - 0.0.0.0:6379 10 | DialTimeout: 0s 11 | ReadTimeout: 0s 12 | WriteTimeout: 0s 13 | mongo: 14 | addr: mongodb://0.0.0.0:27017 15 | user: root 16 | password: "123456" 17 | active: 100 18 | idleTimeout: 4200 19 | log: 20 | logFileDir: logs 21 | appName: app 22 | platform: local 23 | maxSize: 100 24 | maxBackups: 60 25 | maxAge: 30 26 | level: debug -------------------------------------------------------------------------------- /ddd-auth2-example/cmd/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | app, err := NewApp() 5 | if err != nil { 6 | panic(err) 7 | } 8 | app.RunApp() 9 | } 10 | -------------------------------------------------------------------------------- /ddd-auth2-example/domain/aggregate/factory.go: -------------------------------------------------------------------------------- 1 | package aggregate 2 | 3 | import ( 4 | "github.com/hwholiday/learning_tools/ddd-auth2-example/infrastructure/repository" 5 | ) 6 | 7 | type Factory struct { 8 | *AuthFactory 9 | } 10 | 11 | func NewFactory(repo *repository.Repository) *Factory { 12 | return &Factory{ 13 | &AuthFactory{ 14 | merchantRepo: repo.Merchant, 15 | authCodeRepo: repo.AuthCode, 16 | authTokenRepo: repo.AuthToken, 17 | }, 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /ddd-auth2-example/domain/dto/auth_code.go: -------------------------------------------------------------------------------- 1 | package dto 2 | 3 | import ( 4 | "github.com/hwholiday/learning_tools/ddd-auth2-example/infrastructure/pkg/hcode" 5 | "net/url" 6 | ) 7 | 8 | type AuthCodeReq struct { 9 | UID int `json:"uid"` 10 | APPID string `json:"appid"` 11 | Scope string `json:"scope"` //预留参数,后面需要的时间给 12 | RedirectUri string `json:"redirect_uri"` //要跳转的域名 13 | } 14 | 15 | func (a AuthCodeReq) Check() error { 16 | if a.UID <= 0 || len(a.APPID) != 10 || a.Scope == "" { 17 | return hcode.ParameterErr 18 | } 19 | return nil 20 | } 21 | 22 | func (a AuthCodeReq) GetRedirectUriHost() (string, error) { 23 | URL, err := url.Parse(a.RedirectUri) 24 | if err != nil { 25 | return "", hcode.ParameterErr 26 | } 27 | return URL.Host, nil 28 | } 29 | -------------------------------------------------------------------------------- /ddd-auth2-example/domain/dto/user.go: -------------------------------------------------------------------------------- 1 | package dto 2 | 3 | type UserSimple struct { 4 | OpenId string `json:"open_id"` // 用户唯一标示 5 | Username string `json:"user_name"` // 用户名 6 | Phone string `json:"phone"` // 手机号码 7 | Avatar string `json:"avatar"` // 头像 8 | } 9 | -------------------------------------------------------------------------------- /ddd-auth2-example/domain/entity/merchant.go: -------------------------------------------------------------------------------- 1 | package entity 2 | 3 | import ( 4 | "github.com/hwholiday/learning_tools/ddd-auth2-example/infrastructure/pkg/hcode" 5 | "time" 6 | ) 7 | 8 | type Merchant struct { 9 | APPID string `json:"appid" bson:"appid"` 10 | Host string `json:"host" bson:"host"` 11 | Secret string `json:"secret" bson:"secret"` 12 | Scope string `json:"scope"` // 授权范围 ,号分割 13 | StartTime time.Time `json:"start_time" bson:"start_time"` 14 | CreateTime int64 `json:"create_time" bson:"create_time"` 15 | UpdateTime int64 `json:"update_time" bson:"update_time"` 16 | } 17 | 18 | func (m *Merchant) CheckBase() error { 19 | if len(m.APPID) != 10 { 20 | return hcode.ParameterErr 21 | } 22 | if m.Host == "" || m.Secret == "" || m.Scope == "" { 23 | return hcode.ParameterErr 24 | } 25 | return nil 26 | } 27 | -------------------------------------------------------------------------------- /ddd-auth2-example/domain/obj/auth_code.go: -------------------------------------------------------------------------------- 1 | package obj 2 | 3 | type CodeOpenId struct { 4 | Code string `json:"code"` 5 | OpenID string `json:"open_id"` 6 | APPID string `json:"appid"` 7 | Scope string `json:"scope"` 8 | } 9 | -------------------------------------------------------------------------------- /ddd-auth2-example/domain/repo/auth_code.go: -------------------------------------------------------------------------------- 1 | package repo 2 | 3 | import ( 4 | "context" 5 | "github.com/hwholiday/learning_tools/ddd-auth2-example/domain/obj" 6 | ) 7 | 8 | type AuthCodeRepo interface { 9 | CreateCode(ctx context.Context, data obj.CodeOpenId) error 10 | DelCode(ctx context.Context, repo AuthCodeSpecificationRepo) error 11 | QueryCode(ctx context.Context, repo AuthCodeSpecificationRepo) (data obj.CodeOpenId, err error) 12 | } 13 | 14 | type AuthCodeSpecificationRepo interface { 15 | ParameterCheck(ctx context.Context) error 16 | ToSql(ctx context.Context) interface{} 17 | } 18 | -------------------------------------------------------------------------------- /ddd-auth2-example/domain/repo/auth_token.go: -------------------------------------------------------------------------------- 1 | package repo 2 | 3 | import ( 4 | "context" 5 | "github.com/hwholiday/learning_tools/ddd-auth2-example/domain/obj" 6 | ) 7 | 8 | type AuthTokenRepo interface { 9 | CreateAuthToken(ctx context.Context, data obj.AuthToken) error 10 | UpdateAuthToken(ctx context.Context, data obj.AuthToken) error 11 | QueryAuthToken(ctx context.Context, repo AuthTokenSpecificationRepo) (obj.AuthToken, error) 12 | } 13 | 14 | type AuthTokenSpecificationRepo interface { 15 | ParameterCheck(ctx context.Context) error 16 | ToSql(ctx context.Context) interface{} 17 | } 18 | -------------------------------------------------------------------------------- /ddd-auth2-example/domain/repo/merchant.go: -------------------------------------------------------------------------------- 1 | package repo 2 | 3 | import ( 4 | "context" 5 | "github.com/hwholiday/learning_tools/ddd-auth2-example/domain/entity" 6 | ) 7 | 8 | type MerchantRepo interface { 9 | CreateMerChant(ctx context.Context, data *entity.Merchant) error 10 | UpdateMerChant(ctx context.Context, data *entity.Merchant) error 11 | RemoveMerChant(ctx context.Context, data *entity.Merchant) error 12 | QueryMerChant(ctx context.Context, repo MerChantSpecificationRepo) (data *entity.Merchant, err error) 13 | QueryMerChants(ctx context.Context, repo MerChantSpecificationRepo) (data []*entity.Merchant, err error) 14 | } 15 | 16 | type MerChantSpecificationRepo interface { 17 | ParameterCheck(ctx context.Context) error 18 | ToSql(ctx context.Context) interface{} 19 | } 20 | -------------------------------------------------------------------------------- /ddd-auth2-example/domain/repo/specification/auth_code_by_code.go: -------------------------------------------------------------------------------- 1 | package specification 2 | 3 | import ( 4 | "context" 5 | "github.com/hwholiday/learning_tools/ddd-auth2-example/domain/repo" 6 | "github.com/hwholiday/learning_tools/ddd-auth2-example/infrastructure/pkg/hcode" 7 | ) 8 | 9 | type AuthCodeByCode struct { 10 | Code string `json:"code"` 11 | } 12 | 13 | func NewAuthCodeSpecificationByCode(code string) repo.AuthCodeSpecificationRepo { 14 | return &AuthCodeByCode{Code: code} 15 | } 16 | 17 | func (m AuthCodeByCode) ParameterCheck(ctx context.Context) error { 18 | if m.Code == "" { 19 | return hcode.SysParameterErr 20 | } 21 | return nil 22 | } 23 | 24 | func (m AuthCodeByCode) ToSql(ctx context.Context) interface{} { 25 | return m.Code 26 | } 27 | -------------------------------------------------------------------------------- /ddd-auth2-example/domain/repo/specification/auth_token_by_code.go: -------------------------------------------------------------------------------- 1 | package specification 2 | 3 | import ( 4 | "context" 5 | "github.com/hwholiday/learning_tools/ddd-auth2-example/domain/repo" 6 | "github.com/hwholiday/learning_tools/ddd-auth2-example/infrastructure/pkg/hcode" 7 | ) 8 | 9 | type AuthTokenByOpenId struct { 10 | OpenId string `json:"code"` 11 | } 12 | 13 | func NewAuthTokenSpecificationByoOenId(openId string) repo.AuthTokenSpecificationRepo { 14 | return &AuthTokenByOpenId{OpenId: openId} 15 | } 16 | 17 | func (m AuthTokenByOpenId) ParameterCheck(ctx context.Context) error { 18 | if m.OpenId == "" { 19 | return hcode.SysParameterErr 20 | } 21 | return nil 22 | } 23 | 24 | func (m AuthTokenByOpenId) ToSql(ctx context.Context) interface{} { 25 | return m.OpenId 26 | } 27 | -------------------------------------------------------------------------------- /ddd-auth2-example/domain/repo/specification/merchant_by_appid.go: -------------------------------------------------------------------------------- 1 | package specification 2 | 3 | import ( 4 | "context" 5 | "github.com/hwholiday/learning_tools/ddd-auth2-example/domain/repo" 6 | "github.com/hwholiday/learning_tools/ddd-auth2-example/infrastructure/pkg/hcode" 7 | ) 8 | 9 | type MerchantByAppid struct { 10 | APPID string `json:"appid" bson:"appid"` 11 | } 12 | 13 | func NewMerchantSpecificationByAPPID(APPID string) repo.MerChantSpecificationRepo { 14 | return &MerchantByAppid{APPID: APPID} 15 | } 16 | 17 | func (m MerchantByAppid) ParameterCheck(ctx context.Context) error { 18 | if m.APPID == "" { 19 | return hcode.SysParameterErr 20 | } 21 | return nil 22 | } 23 | 24 | func (m MerchantByAppid) ToSql(ctx context.Context) interface{} { 25 | return map[string]string{ 26 | "appid": m.APPID, 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ddd-auth2-example/domain/service/auth_code.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "context" 5 | "github.com/hwholiday/learning_tools/ddd-auth2-example/domain/aggregate" 6 | "github.com/hwholiday/learning_tools/ddd-auth2-example/domain/dto" 7 | "github.com/hwholiday/learning_tools/ddd-auth2-example/domain/repo" 8 | ) 9 | 10 | type AuthCode struct { 11 | factory *aggregate.AuthFactory 12 | authCodeRepo repo.AuthCodeRepo 13 | } 14 | 15 | func (a *AuthCode) CreateCodeOpenId(ctx context.Context, req dto.AuthCodeReq) (string, error) { 16 | if err := req.Check(); err != nil { 17 | return "", err 18 | } 19 | f, err := a.factory.NewAuthCode(ctx, req) 20 | if err != nil { 21 | return "", err 22 | } 23 | return f.CreateCode(ctx) 24 | } 25 | -------------------------------------------------------------------------------- /ddd-auth2-example/infrastructure/conf/auth_consts.go: -------------------------------------------------------------------------------- 1 | package conf 2 | 3 | import "time" 4 | 5 | const ( 6 | AuthCodeCacheKey = "gs:auth:code:" 7 | AuthTokenCacheKey = "gs:auth:token:" 8 | ) 9 | 10 | const ( 11 | AuthCodeCacheKeyTimeout = time.Minute * 2 // code 过期时间 12 | AuthRefreshTokenCacheKeyTimeout = time.Hour * 24 * 30 // RefreshToken 过期时间 13 | AuthAccessTokenCacheKeyTimeout = time.Hour * 24 // AccessToken 过期时间 14 | ) 15 | -------------------------------------------------------------------------------- /ddd-auth2-example/infrastructure/pkg/database/redis/lock.go: -------------------------------------------------------------------------------- 1 | package redis 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/go-redis/redis" 7 | ) 8 | 9 | type RedisLock struct { 10 | conn redis.Cmdable 11 | timeout time.Duration 12 | key string 13 | val string 14 | } 15 | 16 | func NewRedisLock(conn redis.Cmdable, key, val string, timeout time.Duration) *RedisLock { 17 | return &RedisLock{conn: conn, timeout: timeout, key: key, val: val} 18 | } 19 | 20 | // TryLock return true ===> Get the lock successfully 21 | func (lock *RedisLock) TryLock() (bool, error) { 22 | return lock.conn.SetNX(lock.key, lock.val, lock.timeout).Result() 23 | } 24 | 25 | func (lock *RedisLock) UnLock() error { 26 | luaDel := redis.NewScript("if redis.call('get',KEYS[1]) == ARGV[1] then " + 27 | "return redis.call('del',KEYS[1]) else return 0 end") 28 | return luaDel.Run(lock.conn, []string{lock.key}, lock.val).Err() 29 | } 30 | 31 | func (lock *RedisLock) GetLockKey() string { 32 | return lock.key 33 | } 34 | 35 | func (lock *RedisLock) GetLockVal() string { 36 | return lock.val 37 | } 38 | -------------------------------------------------------------------------------- /ddd-auth2-example/infrastructure/pkg/hcode/base.go: -------------------------------------------------------------------------------- 1 | package hcode 2 | 3 | const ( 4 | EN = "en" 5 | ) 6 | 7 | const LanguageLen = 0 8 | 9 | var ( 10 | OK = addCode(200) 11 | ServerErr = addCode(300) 12 | TranErr = addCode(301) 13 | ParameterErr = addCode(304) 14 | RedisExecErr = addCode(305) 15 | ResourcesNotFindErr = addCode(306) 16 | SysParameterErr = addCode(307) 17 | MgoExecErr = addCode(308) 18 | TokenValidErr = addCode(309) 19 | ResourcesAlreadyExistsErr = addCode(310) 20 | ) 21 | 22 | func init() { 23 | 24 | } 25 | -------------------------------------------------------------------------------- /ddd-auth2-example/infrastructure/pkg/tool/aes_test.go: -------------------------------------------------------------------------------- 1 | package tool 2 | 3 | import ( 4 | "github.com/google/uuid" 5 | "net/url" 6 | "strings" 7 | "testing" 8 | ) 9 | 10 | func TestDncrypt(t *testing.T) { 11 | //"1837032330871439" 12 | str, err := AesECBEncrypt("1837032330", []byte("123123123")) 13 | if err != nil { 14 | panic(err) 15 | } 16 | t.Log(str) 17 | res, err := AesECBDecrypt("1837032330", str) 18 | if err != nil { 19 | panic(err) 20 | } 21 | t.Log(string(res)) 22 | } 23 | 24 | func TestUUID(t *testing.T) { 25 | t.Log(strings.ReplaceAll(uuid.New().String(), "-", "")) 26 | } 27 | 28 | func TestUrl(t *testing.T) { 29 | URL := "http://127.0.0.1:8888/a/b" 30 | u, err := url.Parse(URL) 31 | if err != nil { 32 | t.Log(err) 33 | } 34 | t.Log(u.Host) 35 | } 36 | -------------------------------------------------------------------------------- /ddd-auth2-example/infrastructure/pkg/tool/jwt_test.go: -------------------------------------------------------------------------------- 1 | package tool 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | "time" 7 | ) 8 | 9 | func TestCreateAuthToken(t *testing.T) { 10 | res, err := CreateAuthToken(JwtTokenData{ 11 | OpenId: "aaaa", 12 | AppId: "111", 13 | }, time.Second*3) 14 | if err != nil { 15 | t.Error(err) 16 | } 17 | t.Logf("%+v", res) 18 | time.Sleep(time.Second * 5) 19 | fmt.Println(CheckAuthToken(res.Token)) 20 | } 21 | -------------------------------------------------------------------------------- /ddd-auth2-example/infrastructure/repository/repository.go: -------------------------------------------------------------------------------- 1 | package repository 2 | 3 | import ( 4 | "context" 5 | "encoding/json" 6 | "github.com/hwholiday/learning_tools/ddd-auth2-example/infrastructure/pkg/database/redis" 7 | "go.mongodb.org/mongo-driver/mongo" 8 | ) 9 | 10 | type repository struct { 11 | mgo *mongo.Client 12 | rds *redis.Client 13 | } 14 | 15 | type Repository struct { 16 | Merchant *Merchant 17 | AuthCode *AuthCode 18 | AuthToken *AuthToken 19 | } 20 | 21 | func NewRepository(mgo *mongo.Client, r *redis.Client) *Repository { 22 | var a = repository{mgo, r} 23 | return &Repository{ 24 | &Merchant{a}, 25 | &AuthCode{a}, 26 | &AuthToken{a}, 27 | } 28 | } 29 | 30 | func (r *repository) Close() { 31 | if r.mgo != nil { 32 | _ = r.mgo.Disconnect(context.Background()) 33 | } 34 | if r.rds != nil { 35 | _ = r.rds.Close() 36 | } 37 | } 38 | 39 | func Marshal(data interface{}) ([]byte, error) { 40 | return json.Marshal(data) 41 | } 42 | 43 | func Unmarshal(data []byte, v interface{}) error { 44 | return json.Unmarshal(data, v) 45 | } 46 | -------------------------------------------------------------------------------- /ddd-project-example/README.md: -------------------------------------------------------------------------------- 1 | ### Golang DDD 的项目分层结构(六边形架构) 2 | 3 | ```base 4 | ├── cmd 存放 main.go 等 5 | ├── adapter 6 | │   ├── grpc 7 | │   └── http 8 | │   └── facade 引用其他微服务(接口防腐层) 9 | ├── application 10 | │   ├── assembler 负责将内部领域模型转化为可对外的DTO 11 | │   └── cqe Command、Query和Event -- 入参 12 | │   └── dto Application层的所有接口返回值为DTO -- 出参 13 | │   └── service 负责业务流程的编排,但本身不负责任何业务逻辑 14 | ├── domain 15 | │   ├── aggregate 聚合 16 | │   ├── entity 实体 17 | │   ├── event 事件 18 | │   │   ├── publish 19 | │   │   └── subsctibe 20 | │   ├── repo 接口 21 | │   │   └── specification 统一封装查询 22 | │   ├── service 领域服务 23 | │   └── vo 值对象 24 | └── infrastructure 25 | │   ├── config 配置文件 26 | │   ├── pkg 常用工具类封装(DB,log,tool等) 27 | │   └── repository 28 | │   ├── converter domain内对象转化 do {互转} 29 | │   └── do 数据库映射对象 30 | └── types 封装自定义的参数类型,例如 phone 自校验参数 31 | ``` -------------------------------------------------------------------------------- /ddd-project-example/adapter/facade/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hwholiday/learning_tools/71e1320fd3e105ddfde80cc0a88e70d7ad7a41cd/ddd-project-example/adapter/facade/.gitignore -------------------------------------------------------------------------------- /ddd-project-example/adapter/grpc/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hwholiday/learning_tools/71e1320fd3e105ddfde80cc0a88e70d7ad7a41cd/ddd-project-example/adapter/grpc/.gitignore -------------------------------------------------------------------------------- /ddd-project-example/adapter/http/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hwholiday/learning_tools/71e1320fd3e105ddfde80cc0a88e70d7ad7a41cd/ddd-project-example/adapter/http/.gitignore -------------------------------------------------------------------------------- /ddd-project-example/application/assembler/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hwholiday/learning_tools/71e1320fd3e105ddfde80cc0a88e70d7ad7a41cd/ddd-project-example/application/assembler/.gitignore -------------------------------------------------------------------------------- /ddd-project-example/application/cqe/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hwholiday/learning_tools/71e1320fd3e105ddfde80cc0a88e70d7ad7a41cd/ddd-project-example/application/cqe/.gitignore -------------------------------------------------------------------------------- /ddd-project-example/application/dto/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hwholiday/learning_tools/71e1320fd3e105ddfde80cc0a88e70d7ad7a41cd/ddd-project-example/application/dto/.gitignore -------------------------------------------------------------------------------- /ddd-project-example/application/service/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hwholiday/learning_tools/71e1320fd3e105ddfde80cc0a88e70d7ad7a41cd/ddd-project-example/application/service/.gitignore -------------------------------------------------------------------------------- /ddd-project-example/cmd/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hwholiday/learning_tools/71e1320fd3e105ddfde80cc0a88e70d7ad7a41cd/ddd-project-example/cmd/.gitignore -------------------------------------------------------------------------------- /ddd-project-example/domain/aggregate/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hwholiday/learning_tools/71e1320fd3e105ddfde80cc0a88e70d7ad7a41cd/ddd-project-example/domain/aggregate/.gitignore -------------------------------------------------------------------------------- /ddd-project-example/domain/entity/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hwholiday/learning_tools/71e1320fd3e105ddfde80cc0a88e70d7ad7a41cd/ddd-project-example/domain/entity/.gitignore -------------------------------------------------------------------------------- /ddd-project-example/domain/event/publish/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hwholiday/learning_tools/71e1320fd3e105ddfde80cc0a88e70d7ad7a41cd/ddd-project-example/domain/event/publish/.gitignore -------------------------------------------------------------------------------- /ddd-project-example/domain/event/subsctibe/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hwholiday/learning_tools/71e1320fd3e105ddfde80cc0a88e70d7ad7a41cd/ddd-project-example/domain/event/subsctibe/.gitignore -------------------------------------------------------------------------------- /ddd-project-example/domain/repo/specification/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hwholiday/learning_tools/71e1320fd3e105ddfde80cc0a88e70d7ad7a41cd/ddd-project-example/domain/repo/specification/.gitignore -------------------------------------------------------------------------------- /ddd-project-example/domain/service/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hwholiday/learning_tools/71e1320fd3e105ddfde80cc0a88e70d7ad7a41cd/ddd-project-example/domain/service/.gitignore -------------------------------------------------------------------------------- /ddd-project-example/domain/vo/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hwholiday/learning_tools/71e1320fd3e105ddfde80cc0a88e70d7ad7a41cd/ddd-project-example/domain/vo/.gitignore -------------------------------------------------------------------------------- /ddd-project-example/infrastructure/config/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hwholiday/learning_tools/71e1320fd3e105ddfde80cc0a88e70d7ad7a41cd/ddd-project-example/infrastructure/config/.gitignore -------------------------------------------------------------------------------- /ddd-project-example/infrastructure/pkg/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hwholiday/learning_tools/71e1320fd3e105ddfde80cc0a88e70d7ad7a41cd/ddd-project-example/infrastructure/pkg/.gitignore -------------------------------------------------------------------------------- /ddd-project-example/infrastructure/repository/converter/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hwholiday/learning_tools/71e1320fd3e105ddfde80cc0a88e70d7ad7a41cd/ddd-project-example/infrastructure/repository/converter/.gitignore -------------------------------------------------------------------------------- /ddd-project-example/infrastructure/repository/do/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hwholiday/learning_tools/71e1320fd3e105ddfde80cc0a88e70d7ad7a41cd/ddd-project-example/infrastructure/repository/do/.gitignore -------------------------------------------------------------------------------- /ddd-project-example/types/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hwholiday/learning_tools/71e1320fd3e105ddfde80cc0a88e70d7ad7a41cd/ddd-project-example/types/.gitignore -------------------------------------------------------------------------------- /design-patterns/README.md: -------------------------------------------------------------------------------- 1 | ### [active_object](https://github.com/hwholiday/learning_tools/tree/master/design-patterns/active_object) (并发设计模式) 2 | 3 | 1: active_object Go并发设计模式之Active Object 4 | 5 | ### [chainOfResponsibility](https://github.com/hwholiday/learning_tools/tree/master/design-patterns/chainOfResponsibility) (责任链模式) 6 | 7 | 1: chainOfResponsibility Go 实现的责任链模式 8 | ### [builder](https://github.com/hwholiday/learning_tools/tree/master/design-patterns/builder) (构造者模式) 9 | 10 | 1: builder Go 实现的构造者模式 11 | 12 | ### [options](https://github.com/hwholiday/learning_tools/tree/master/design-patterns/options) (options模式) 13 | 14 | 1: options Go 实现的options模式 -------------------------------------------------------------------------------- /design-patterns/active_object/active_object.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | const ( 9 | Add = 1 10 | Lessen = 2 11 | ) 12 | 13 | type Service struct { 14 | queue chan int 15 | val int 16 | } 17 | 18 | func NewService(buffer int) *Service { 19 | info := &Service{queue: make(chan int, buffer)} 20 | go info.schedule() 21 | return info 22 | } 23 | 24 | func (s *Service) schedule() { 25 | for { 26 | select { 27 | case i := <-s.queue: 28 | if i == Add { 29 | fmt.Println("s.val++") 30 | s.val++ 31 | } else if i == Lessen { 32 | fmt.Println("s.val--") 33 | s.val-- 34 | } 35 | case <-time.After(time.Second * 5): 36 | fmt.Println("5秒没有写入") 37 | } 38 | } 39 | } 40 | 41 | func (s *Service) Add() { 42 | fmt.Println("s.queue <- Add") 43 | s.queue <- Add 44 | } 45 | 46 | func (s *Service) Lessen() { 47 | fmt.Println("s.queue <- Lessen") 48 | s.queue <- Lessen 49 | } 50 | -------------------------------------------------------------------------------- /design-patterns/active_object/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | // Go并发设计模式之 Active Object 9 | // https://colobu.com/2019/07/02/concurrency-design-patterns-active-object/ 10 | func main() { 11 | info := NewService(1) 12 | for i := 0; i < 20; i++ { 13 | info.Add() 14 | fmt.Println(info.val) //不是同步返回值 15 | //info.Lessen() 16 | //fmt.Println(info.val) 17 | } 18 | fmt.Println(info.val) 19 | time.Sleep(time.Hour) 20 | } 21 | -------------------------------------------------------------------------------- /design-patterns/builder/builder.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/pkg/errors" 5 | ) 6 | 7 | type User struct { 8 | Name string 9 | Age int 10 | } 11 | type UserBuilder struct { 12 | User 13 | err error 14 | } 15 | 16 | func defaultUser() User { 17 | return User{ 18 | Name: "", 19 | Age: 0, 20 | } 21 | } 22 | 23 | func NewUserBuilder() *UserBuilder { 24 | return &UserBuilder{ 25 | User: defaultUser(), 26 | } 27 | } 28 | 29 | func (b *UserBuilder) WithName(n string) *UserBuilder { 30 | if b.err != nil { 31 | return b 32 | } 33 | if n == "" { 34 | b.err = errors.New("name is empty") 35 | } 36 | b.Name = n 37 | return b 38 | } 39 | 40 | func (b *UserBuilder) WithAge(a int) *UserBuilder { 41 | if b.err != nil { 42 | return b 43 | } 44 | if a == 0 { 45 | b.err = errors.New("age is empty") 46 | } 47 | b.Age = a 48 | return b 49 | } 50 | 51 | func (b *UserBuilder) Builder() (*User, error) { 52 | if b.err != nil { 53 | return nil, b.err 54 | } 55 | return &b.User, nil 56 | } 57 | -------------------------------------------------------------------------------- /design-patterns/builder/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | user, err := NewUserBuilder().WithName("").Builder() 7 | if err != nil { 8 | panic(err) 9 | } 10 | fmt.Printf("%+v", user) 11 | } 12 | -------------------------------------------------------------------------------- /design-patterns/chainOfResponsibility/chainofresponsibility.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type Task struct { 6 | Name string 7 | TaskA string 8 | TaskB string 9 | TaskC string 10 | } 11 | 12 | type TaskHandler interface { 13 | NextHandler(TaskHandler) TaskHandler 14 | Do(*Task) error 15 | Execute(*Task) error 16 | } 17 | 18 | type BaseHandler struct { 19 | nextTaskHandler TaskHandler 20 | } 21 | 22 | func (h *BaseHandler) NextHandler(task TaskHandler) TaskHandler { 23 | h.nextTaskHandler = task 24 | return task 25 | } 26 | 27 | func (h *BaseHandler) Execute(task *Task) error { 28 | if h.nextTaskHandler != nil { 29 | if err := h.nextTaskHandler.Do(task); err != nil { 30 | return err 31 | } 32 | return h.nextTaskHandler.Execute(task) 33 | } 34 | return nil 35 | } 36 | 37 | type StartHandler struct { 38 | BaseHandler 39 | } 40 | 41 | func (s *StartHandler) Do(task *Task) error { 42 | fmt.Println("StartHandler") 43 | return nil 44 | } 45 | -------------------------------------------------------------------------------- /design-patterns/chainOfResponsibility/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | s := StartHandler{} 7 | s.NextHandler(&TaskA{}).NextHandler(&TaskB{}).NextHandler(&TaskC{}) 8 | var task = &Task{ 9 | Name: "test", 10 | } 11 | if err := s.Execute(task); err != nil { 12 | panic(err) 13 | } 14 | fmt.Printf("%+v\n", task) 15 | } 16 | -------------------------------------------------------------------------------- /design-patterns/chainOfResponsibility/task.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type TaskA struct { 6 | BaseHandler 7 | } 8 | 9 | func (t *TaskA) Do(task *Task) error { 10 | task.TaskA = "TaskA" 11 | fmt.Println("TaskA") 12 | return nil 13 | } 14 | 15 | type TaskB struct { 16 | BaseHandler 17 | } 18 | 19 | func (t *TaskB) Do(task *Task) error { 20 | task.TaskB = "TaskB" 21 | fmt.Println("TaskB") 22 | return nil 23 | } 24 | 25 | type TaskC struct { 26 | BaseHandler 27 | } 28 | 29 | func (t *TaskC) Do(task *Task) error { 30 | task.TaskC = "TaskC" 31 | fmt.Println("TaskC") 32 | return nil 33 | } 34 | -------------------------------------------------------------------------------- /design-patterns/options/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | opt := NewUserOptions(WithName("aaa"), WithAge(2)) 7 | fmt.Printf("%+v", opt) 8 | } 9 | -------------------------------------------------------------------------------- /design-patterns/options/option.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type Options struct { 4 | Name string 5 | Age int 6 | } 7 | 8 | func defaultOptions() *Options { 9 | return &Options{ 10 | Name: "", 11 | Age: 0, 12 | } 13 | } 14 | 15 | type FOptions func(*Options) 16 | 17 | func WithName(n string) FOptions { 18 | return func(options *Options) { 19 | options.Name = n 20 | } 21 | } 22 | 23 | func WithAge(a int) FOptions { 24 | return func(options *Options) { 25 | options.Age = a 26 | } 27 | } 28 | 29 | func NewUserOptions(opt ...FOptions) *Options { 30 | o := defaultOptions() 31 | for _, f := range opt { 32 | f(o) 33 | } 34 | return o 35 | } 36 | -------------------------------------------------------------------------------- /docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM scratch 2 | MAINTAINER hwholiday 3 | ADD agent /server/http/ 4 | ENTRYPOINT ["/server/http/agent"] 5 | 6 | 7 | -------------------------------------------------------------------------------- /docker/build.sh: -------------------------------------------------------------------------------- 1 | CGO_ENABLED=0 GOOS=linux go build -a -ldflags '-extldflags "-static"' -o agent . 2 | 3 | sudo docker-compose -f docker-compose.yml up 4 | 5 | sudo docker-compose -f docker-compose.yml up agent 6 | 7 | sudo docker-compose -f docker-compose.yml down -------------------------------------------------------------------------------- /docker/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | services: 3 | agent: 4 | hostname: "agent" 5 | container_name: agent 6 | restart: always 7 | build: 8 | context: . 9 | dockerfile: Dockerfile 10 | ports: 11 | - "9999:9999" 12 | depends_on: 13 | - redis 14 | networks: 15 | - back 16 | redis: 17 | image: redis 18 | hostname: "redis" 19 | container_name: redis 20 | restart: always 21 | volumes: 22 | - /home/ghost/redis:/data 23 | command: redis-server --requirepass 123456 24 | networks: 25 | - back 26 | networks: 27 | back: -------------------------------------------------------------------------------- /ebcdic/EBCDIC.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hwholiday/learning_tools/71e1320fd3e105ddfde80cc0a88e70d7ad7a41cd/ebcdic/EBCDIC.txt -------------------------------------------------------------------------------- /ebcdic/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | ) 7 | 8 | func main() { 9 | data, err := os.ReadFile("/home/jk/projects/go/src/learning_tools/dd/EBCDIC.txt") 10 | if err != nil { 11 | panic(err) 12 | } 13 | fmt.Println(data) 14 | fmt.Print(EncodeToString(data)) 15 | fmt.Println(string(data)) 16 | } 17 | -------------------------------------------------------------------------------- /encryption_algorithm/dh_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/big" 6 | "testing" 7 | ) 8 | 9 | func TestDh(t *testing.T) { 10 | aP := big.NewInt(509) //素数 11 | aG := big.NewInt(5) //底数g,任选 12 | aS := big.NewInt(123) //随机数 13 | AA := big.NewInt(0).Exp(aG, aS, aP) //// aG^aS mod aP 14 | fmt.Println(AA) 15 | //发给B aG,AA,aP 16 | bS := big.NewInt(456) //随机数 17 | BB := big.NewInt(0).Exp(aG, bS, aP) 18 | fmt.Println(BB) 19 | BK := big.NewInt(0).Exp(AA, bS, aP) 20 | fmt.Println("密钥", BK) 21 | //发给A BB 22 | AK := big.NewInt(0).Exp(BB, aS, aP) 23 | fmt.Println("密钥", AK) 24 | 25 | } 26 | -------------------------------------------------------------------------------- /encryption_algorithm/kdf_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "crypto/rand" 5 | "crypto/sha256" 6 | "encoding/base64" 7 | "fmt" 8 | "golang.org/x/crypto/hkdf" 9 | "io" 10 | "testing" 11 | ) 12 | 13 | func TestKDF(t *testing.T) { 14 | hash := sha256.New 15 | 16 | secret := []byte("123456") 17 | 18 | salt := make([]byte, hash().Size()) 19 | if _, err := rand.Read(salt); err != nil { 20 | panic(err) 21 | } 22 | info := []byte("user pwd") 23 | hkdf := hkdf.New(hash, secret, salt, info) 24 | key := make([]byte, 16) 25 | if _, err := io.ReadFull(hkdf, key); err != nil { 26 | panic(err) 27 | } 28 | fmt.Println("key", key) 29 | fmt.Println("key", base64.StdEncoding.EncodeToString(key[:])) 30 | } 31 | -------------------------------------------------------------------------------- /err/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "time" 7 | ) 8 | 9 | type MyError struct { 10 | Name string 11 | time.Time 12 | Err error 13 | } 14 | 15 | func (m MyError) Error() string { 16 | return fmt.Sprintf("%v %v %v", m.Name, m.Time, m.Err) 17 | } 18 | func (m MyError) Unwrap() error { 19 | return m.Err 20 | } 21 | 22 | func TestErr() error { 23 | return MyError{ 24 | Name: "AAAA", 25 | Time: time.Now(), 26 | } 27 | } 28 | 29 | func main() { 30 | err := Test() 31 | fmt.Println("产生的错误", err) 32 | var testErr MyError 33 | fmt.Println("解析错误内容", errors.As(err, &testErr)) //查询err里面是否有自定义的MyError错误,并解除其中数据 34 | fmt.Println(testErr) 35 | fmt.Println("判断是否有该错误", errors.Is(err, testErr)) //是否包含该错误 36 | fmt.Println("去掉最上的错误", errors.Unwrap(err)) 37 | 38 | } 39 | 40 | func Test() error { 41 | err := TestErr() 42 | err = fmt.Errorf("加入第一个错误%w", err) 43 | return err 44 | } 45 | -------------------------------------------------------------------------------- /es/README.md: -------------------------------------------------------------------------------- 1 | docker run --name es -d -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.2.0 2 | 3 | 4 | unzip elasticsearch-analysis-ik-7.2.0.zip -d ik 5 | 6 | 7 | docker cp ik es:/usr/share/elasticsearch/plugins/ik/ 8 | 9 | docker restart es -------------------------------------------------------------------------------- /es/go.mod: -------------------------------------------------------------------------------- 1 | module learning_tools/es 2 | 3 | go 1.15 4 | 5 | require github.com/olivere/elastic/v7 v7.0.22 6 | -------------------------------------------------------------------------------- /etcd/etcd-grpc/api.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package proto; 3 | option go_package = "/api"; 4 | 5 | message Request { 6 | string input = 1; 7 | } 8 | 9 | message Response { 10 | string output = 1; 11 | } 12 | //protoc -I. --go_out=plugins=grpc:. api.proto 13 | service Api{ 14 | rpc ApiTest (Request) returns (Response){} 15 | } -------------------------------------------------------------------------------- /etcd/lock/etcd.go: -------------------------------------------------------------------------------- 1 | package lock 2 | 3 | import ( 4 | clientv3 "go.etcd.io/etcd/client/v3" 5 | "time" 6 | ) 7 | 8 | type Conf struct { 9 | Addr []string 10 | DialTimeout int 11 | } 12 | 13 | func NewEtcd(c *Conf) *clientv3.Client { 14 | cli, err := clientv3.New(clientv3.Config{ 15 | Endpoints: c.Addr, 16 | DialTimeout: time.Duration(c.DialTimeout) * time.Second, 17 | }) 18 | if err != nil { 19 | panic(err) 20 | } 21 | return cli 22 | } 23 | -------------------------------------------------------------------------------- /etcd/lock/etcd_lock_test.go: -------------------------------------------------------------------------------- 1 | package lock 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | "time" 7 | ) 8 | 9 | func TestEtcdLock_TryLock(t *testing.T) { 10 | cli := NewEtcd(&Conf{ 11 | Addr: []string{"127.0.0.1:2379"}, 12 | DialTimeout: 5, 13 | }) 14 | lock := NewEtcdLock(cli, "/get/post", 5) 15 | 16 | if err := lock.TryLock(); err != nil { 17 | fmt.Println("1 err", err) 18 | return 19 | } 20 | fmt.Println("1 success") 21 | go fmt.Println(lock.TryLock()) 22 | go fmt.Println(lock.TryLock()) 23 | go fmt.Println(lock.TryLock()) 24 | go fmt.Println(lock.TryLock()) 25 | go fmt.Println(lock.TryLock()) 26 | time.Sleep(3 * time.Second) 27 | fmt.Println(1, lock.UnLock()) 28 | go func() { 29 | time.Sleep(6 * time.Second) 30 | if err := lock.TryLock(); err != nil { 31 | fmt.Println("2 err") 32 | return 33 | } 34 | fmt.Println("2 success") 35 | }() 36 | go func() { 37 | time.Sleep(6 * time.Second) 38 | if err := lock.TryLock(); err != nil { 39 | fmt.Println("3 err") 40 | return 41 | } 42 | fmt.Println("3 success") 43 | }() 44 | select {} 45 | } 46 | -------------------------------------------------------------------------------- /etcd/register/register_test.go: -------------------------------------------------------------------------------- 1 | package register 2 | 3 | import ( 4 | "fmt" 5 | clientv3 "go.etcd.io/etcd/client/v3" 6 | "os" 7 | "os/signal" 8 | "syscall" 9 | "testing" 10 | "time" 11 | ) 12 | 13 | func TestNewServiceRegister(t *testing.T) { 14 | s, err := NewRegister( 15 | SetName("hwholiday.srv.msg"), 16 | SetAddress("127.0.0.1:123123"), 17 | SetVersion("v1"), 18 | SetEtcdConf(clientv3.Config{ 19 | Endpoints: []string{"172.12.12.165:2379"}, 20 | DialTimeout: time.Second * 5, 21 | }), 22 | ) 23 | if err != nil { 24 | panic(err) 25 | } 26 | c := make(chan os.Signal, 1) 27 | go func() { 28 | if s.ListenKeepAliveChan() { 29 | c <- syscall.SIGQUIT 30 | } 31 | }() 32 | signal.Notify(c, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT) 33 | for a := range c { 34 | switch a { 35 | case syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT: 36 | fmt.Println("退出") 37 | _ = s.Close() 38 | return 39 | default: 40 | return 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /game/elo/elo_test.go: -------------------------------------------------------------------------------- 1 | package elo 2 | 3 | import "testing" 4 | 5 | func Test_EloRating(t *testing.T) { 6 | a, b := EloRating(Elo{ 7 | A: 1500, 8 | B: 1600, 9 | Sa: 1, 10 | }) 11 | t.Log("a", a) 12 | t.Log("b", b) 13 | } 14 | 15 | func Test_Decimal(t *testing.T) { 16 | t.Log(Decimal(22.222222222, "%.2f")) 17 | t.Log(Decimal(22.222222222, "%.0f")) 18 | t.Log(Decimal(22.6666666666, "%.2f")) 19 | t.Log(Decimal(22.66666666666, "%.0f")) 20 | } 21 | -------------------------------------------------------------------------------- /game/match/match_test.go: -------------------------------------------------------------------------------- 1 | package match 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | ) 7 | 8 | func Test_NewMatchPool(t *testing.T) { 9 | macth := NewMatchPool(100000, 2) 10 | macth.Add(&Match{ 11 | Uid: 1, 12 | Rating: 1661, 13 | StartTime: time.Now().UnixNano() / 1e6, 14 | }) 15 | time.Sleep(time.Second) 16 | macth.Add(&Match{ 17 | Uid: 2, 18 | Rating: 1662, 19 | StartTime: time.Now().UnixNano() / 1e6, 20 | }) 21 | macth.Run() 22 | time.Sleep(time.Hour) 23 | } 24 | 25 | func TestMatchPool_AddV1(t *testing.T) { 26 | var middle = 100 27 | for searchRankUp, searchRankDown := middle, middle; searchRankUp <= 120 && searchRankDown >= 80; searchRankUp, searchRankDown = searchRankUp+1, searchRankDown-1 { 28 | t.Log("searchRankUp: ", searchRankUp) 29 | t.Log("searchRankDown: ", searchRankDown) 30 | if searchRankDown != searchRankUp && searchRankDown > 0 { 31 | t.Log("searchRankDown: searchRankDownsearchRankDownsearchRankDown ", searchRankDown) 32 | } 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /gcache/chace.go: -------------------------------------------------------------------------------- 1 | package gcache 2 | 3 | import "sync" 4 | 5 | type cache struct { 6 | mu sync.Mutex 7 | lru *LRU 8 | maxCacheBytes int64 9 | } 10 | 11 | func (c *cache) add(key string, val []byte) { 12 | c.mu.Lock() 13 | defer c.mu.Unlock() 14 | if c.lru == nil { 15 | c.lru = NewLRU(c.maxCacheBytes, nil) 16 | } 17 | c.lru.Add(key, val) 18 | } 19 | 20 | func (c *cache) get(key string) (val []byte, ok bool) { 21 | c.mu.Lock() 22 | defer c.mu.Unlock() 23 | if c.lru == nil { 24 | return 25 | } 26 | val, ok = c.lru.Get(key) 27 | return 28 | } 29 | 30 | func (c *cache) del(key string) { 31 | c.mu.Lock() 32 | defer c.mu.Unlock() 33 | c.del(key) 34 | return 35 | } 36 | -------------------------------------------------------------------------------- /gcache/gchace_test.go: -------------------------------------------------------------------------------- 1 | package gcache 2 | 3 | import "testing" 4 | 5 | func TestNewGroups(t *testing.T) { 6 | g := NewGroups("user", 0, GetterFunc( 7 | func(key string) ([]byte, error) { 8 | t.Log("GetterFunc key : ", key) 9 | if key == "1" { 10 | return []byte("111111111111111"), nil 11 | } 12 | return nil, nil 13 | })) 14 | val, err := g.Get("1") 15 | if err != nil { 16 | t.Fatal(err) 17 | } 18 | t.Log(string(val)) 19 | val, err = g.Get("1") 20 | if err != nil { 21 | t.Fatal(err) 22 | } 23 | t.Log(string(val)) 24 | } 25 | -------------------------------------------------------------------------------- /gcache/lru_test.go: -------------------------------------------------------------------------------- 1 | package gcache 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestNewGCache(t *testing.T) { 8 | lru := NewLRU(0, nil) 9 | lru.Add("1", []byte("1")) 10 | val, ok := lru.Get("1") 11 | if !ok { 12 | t.Fatalf("lru not get") 13 | } 14 | if string(val) != "1" { 15 | t.Fatalf("lru get val err") 16 | } 17 | t.Log("val : ", string(val)) 18 | lru.Del("1") 19 | _, ok = lru.Get("1") 20 | if ok { 21 | t.Fatalf("lru del err") 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /gin/conf/mysql.json: -------------------------------------------------------------------------------- 1 | { 2 | "mysqluser":"root", 3 | "mysqlpass":"nihao123,./", 4 | "mysqlurl":"192.168.2.15", 5 | "mysqlport":"3306", 6 | "mysqldb":"online" 7 | } 8 | -------------------------------------------------------------------------------- /gin/conf/seelog.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /gin/controller/base.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | import ( 4 | "github.com/gin-gonic/gin" 5 | ) 6 | 7 | type BaseController struct { 8 | } 9 | 10 | func (c *BaseController) ResponseSuccess(g *gin.Context) { 11 | g.JSON(200, gin.H{ 12 | "code": 200, 13 | "data": "", 14 | "msg": "操作成功", 15 | }) 16 | } 17 | 18 | func (c *BaseController) ResponseData(g *gin.Context, data interface{}) { 19 | g.JSON(200, gin.H{ 20 | "code": 200, 21 | "data": data, 22 | "msg": "操作成功", 23 | }) 24 | } 25 | 26 | func (c *BaseController) ResponseFailureForParameter(g *gin.Context, err interface{}) { 27 | g.JSON(403, gin.H{ 28 | "code": 403, 29 | "data": "", 30 | "msg": err, 31 | }) 32 | } 33 | 34 | func (c *BaseController) ResponseFailureForFuncErr(g *gin.Context, err interface{}) { 35 | g.JSON(500, gin.H{ 36 | "code": 500, 37 | "data": "", 38 | "msg": err, 39 | }) 40 | } 41 | 42 | func (c *BaseController) ResponseFailure(g *gin.Context, httpCode, code int, err interface{}) { 43 | g.JSON(httpCode, gin.H{ 44 | "code": code, 45 | "data": "", 46 | "msg": err, 47 | }) 48 | } 49 | -------------------------------------------------------------------------------- /gin/controller/code.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | const ( 4 | CErrParam = "未获取到要操作的对象ID" 5 | CErrJSON = "获取JSON数据失败" 6 | CErrTypeConversion = "类型转换错误" 7 | ) 8 | -------------------------------------------------------------------------------- /gin/log/other.log.27.07.2018: -------------------------------------------------------------------------------- 1 | 2018-07-27 14:30:59 [INF] [main.go:36] [main.main] server run :127.0.0.1:8081 2 | 2018-07-27 14:30:59 [DBG] [main.go:36] [main.main] 111 3 | 2018-07-27 14:31:06 [INF] [main.go:36] [main.main] server run :127.0.0.1:8081 4 | 2018-07-27 14:31:06 [DBG] [main.go:36] [main.main] 111 5 | 2018-07-27 14:31:06 [ERR] [main.go:40] [main.main] listen tcp 127.0.0.1:8081: bind: address already in use 6 | -------------------------------------------------------------------------------- /gin/model/code.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | const ( 4 | MErrExisted = "该数据已经存在" 5 | MErrDelete = "该数据删除失败" 6 | MErrUpdate = "该内容修改失败" 7 | MErrNotFind = "没有查询到数据" 8 | ) 9 | -------------------------------------------------------------------------------- /gin/protos/source/annoucement.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package protos; 3 | 4 | message Annoucement { 5 | int64 Id = 1; 6 | string Title = 2; 7 | string Content = 3; 8 | string Url = 4; 9 | int64 CreateTime = 5; 10 | int64 UpdateTime = 6; 11 | int64 ExpiredTime = 7; 12 | } 13 | 14 | -------------------------------------------------------------------------------- /gitconfig.sh: -------------------------------------------------------------------------------- 1 | git config user.name "hwholiday" 2 | git config user.email "heweiholiday@gmail.com" -------------------------------------------------------------------------------- /go-kit/v1/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/hwholiday/learning_tools/go-kit/v1/v1_endpoint" 6 | "github.com/hwholiday/learning_tools/go-kit/v1/v1_service" 7 | "github.com/hwholiday/learning_tools/go-kit/v1/v1_transport" 8 | "net/http" 9 | ) 10 | 11 | func main() { 12 | server := v1_service.NewService() 13 | endpoints := v1_endpoint.NewEndPointServer(server) 14 | httpHandler := v1_transport.NewHttpHandler(endpoints) 15 | fmt.Println("server run 0.0.0.0:8888") 16 | _ = http.ListenAndServe("0.0.0.0:8888", httpHandler) 17 | } 18 | -------------------------------------------------------------------------------- /go-kit/v1/v1_endpoint/endpoint.go: -------------------------------------------------------------------------------- 1 | package v1_endpoint 2 | 3 | import ( 4 | "context" 5 | "github.com/go-kit/kit/endpoint" 6 | "github.com/hwholiday/learning_tools/go-kit/v1/v1_service" 7 | ) 8 | 9 | type EndPointServer struct { 10 | AddEndPoint endpoint.Endpoint 11 | } 12 | 13 | func NewEndPointServer(svc v1_service.Service) EndPointServer { 14 | var addEndPoint endpoint.Endpoint 15 | { 16 | addEndPoint = MakeAddEndPoint(svc) 17 | } 18 | return EndPointServer{AddEndPoint: addEndPoint} 19 | } 20 | 21 | func (s EndPointServer) Add(ctx context.Context, in v1_service.Add) v1_service.AddAck { 22 | res, _ := s.AddEndPoint(ctx, in) 23 | return res.(v1_service.AddAck) 24 | } 25 | 26 | func MakeAddEndPoint(s v1_service.Service) endpoint.Endpoint { 27 | return func(ctx context.Context, request interface{}) (response interface{}, err error) { 28 | req := request.(v1_service.Add) 29 | res := s.TestAdd(ctx, req) 30 | return res, nil 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /go-kit/v1/v1_service/model.go: -------------------------------------------------------------------------------- 1 | package v1_service 2 | 3 | type Add struct { 4 | A int `json:"a"` 5 | B int `json:"b"` 6 | } 7 | 8 | type AddAck struct { 9 | Res int `json:"res"` 10 | } 11 | -------------------------------------------------------------------------------- /go-kit/v1/v1_service/service.go: -------------------------------------------------------------------------------- 1 | package v1_service 2 | 3 | import "context" 4 | 5 | type Service interface { 6 | TestAdd(ctx context.Context, in Add) AddAck 7 | } 8 | 9 | type baseServer struct { 10 | } 11 | 12 | func NewService() Service { 13 | return &baseServer{} 14 | } 15 | 16 | func (s baseServer) TestAdd(ctx context.Context, in Add) AddAck { 17 | return AddAck{Res: in.A + in.B} 18 | } 19 | -------------------------------------------------------------------------------- /go-kit/v11/filebeat_v11.yml: -------------------------------------------------------------------------------- 1 | filebeat.inputs: 2 | - type: log 3 | enabled: true 4 | paths: 5 | - /home/go/src/learning_tools/logs/go-kit-v11-client-*.log 6 | document_type: "kit-client" #指定类型 在elastic中可通过[type]识别 7 | fields: 8 | tag: kit-client #指定标签 在logstahs中可通过[fields][tag]识别 9 | - type: log 10 | enabled: true 11 | paths: 12 | - /home/go/src/learning_tools/logs/go-kit-v11-server-*.log 13 | document_type: "kit-server" 14 | fields: 15 | tag: kit-server 16 | 17 | # 积累1024条消息才上报 18 | #spool_size: 1024 19 | # 或者空闲5s上报 20 | #idle_timeout: "5s" 21 | 22 | output.logstash: 23 | hosts: ["0.0.0.0:5044"] 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /go-kit/v11/logstash-sample.conf: -------------------------------------------------------------------------------- 1 | # Sample Logstash configuration for creating a simple 2 | # Beats -> Logstash -> Elasticsearch pipeline. 3 | 4 | input { 5 | beats { 6 | port => 5044 7 | } 8 | } 9 | 10 | output { 11 | 12 | stdout { 13 | codec => rubydebug 14 | } 15 | 16 | if [fields][tag] == "kit-server" 17 | { 18 | elasticsearch { 19 | hosts => ["http://localhost:9200"] 20 | index => "kit-server-%{+YYYY.MM.dd}" 21 | } 22 | } 23 | 24 | if [fields][tag] == "kit-client" 25 | { 26 | elasticsearch { 27 | hosts => ["http://localhost:9200"] 28 | index => "kit-client-%{+YYYY.MM.dd}" 29 | } 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /go-kit/v11/user_agent/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM scratch 2 | ADD user_agent / 3 | WORKDIR / 4 | ENTRYPOINT ["user_agent"] -------------------------------------------------------------------------------- /go-kit/v11/user_agent/build.sh: -------------------------------------------------------------------------------- 1 | CGO_ENABLED=0 GOOS=linux go build -a -ldflags '-extldflags "-static"' -o user_agent . 2 | -------------------------------------------------------------------------------- /go-kit/v11/user_agent/pb/make.sh: -------------------------------------------------------------------------------- 1 | protoc --go_out=plugins=grpc:. *.proto -------------------------------------------------------------------------------- /go-kit/v11/user_agent/pb/service.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package pb; 3 | import "user.proto"; 4 | service User { 5 | rpc RpcUserLogin (Login) returns (LoginAck) { 6 | } 7 | } -------------------------------------------------------------------------------- /go-kit/v11/user_agent/pb/user.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package pb; 3 | 4 | message Login { 5 | string Account = 1; 6 | string Password = 2; 7 | } 8 | 9 | message LoginAck { 10 | string Token = 1; 11 | string err = 2; 12 | } -------------------------------------------------------------------------------- /go-kit/v11/user_agent/src/middleware_log.go: -------------------------------------------------------------------------------- 1 | package src 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "github.com/hwholiday/learning_tools/go-kit/v11/utils" 7 | "go.uber.org/zap" 8 | "time" 9 | ) 10 | 11 | type NewMiddlewareServer func(Service) Service 12 | 13 | type logMiddlewareServer struct { 14 | logger *zap.Logger 15 | next Service 16 | } 17 | 18 | func NewLogMiddlewareServer(log *zap.Logger) NewMiddlewareServer { 19 | return func(service Service) Service { 20 | return logMiddlewareServer{ 21 | logger: log, 22 | next: service, 23 | } 24 | } 25 | } 26 | 27 | func (l logMiddlewareServer) Login(ctx context.Context, in Login) (out LoginAck, err error) { 28 | defer func(start time.Time) { 29 | l.logger.Debug(fmt.Sprint(ctx.Value(utils.ContextReqUUid)), zap.Any("调用 Login logMiddlewareServer", "Login"), zap.Any("req", in), zap.Any("res", out), zap.Any("time", time.Since(start)), zap.Any("err", err)) 30 | }(time.Now()) 31 | out, err = l.next.Login(ctx, in) 32 | return 33 | } 34 | -------------------------------------------------------------------------------- /go-kit/v11/user_agent/src/middleware_metrics.go: -------------------------------------------------------------------------------- 1 | package src 2 | 3 | import ( 4 | "context" 5 | "github.com/go-kit/kit/metrics" 6 | "time" 7 | ) 8 | 9 | type metricsMiddlewareServer struct { 10 | next Service 11 | counter metrics.Counter 12 | histogram metrics.Histogram 13 | } 14 | 15 | func NewMetricsMiddlewareServer(counter metrics.Counter, histogram metrics.Histogram) NewMiddlewareServer { 16 | return func(service Service) Service { 17 | return metricsMiddlewareServer{ 18 | next: service, 19 | counter: counter, 20 | histogram: histogram, 21 | } 22 | } 23 | } 24 | 25 | func (l metricsMiddlewareServer) Login(ctx context.Context, in Login) (out LoginAck, err error) { 26 | defer func(start time.Time) { 27 | method := []string{"method", "login"} 28 | l.counter.With(method...).Add(1) 29 | l.histogram.With(method...).Observe(time.Since(start).Seconds()) 30 | }(time.Now()) 31 | out, err = l.next.Login(ctx, in) 32 | return 33 | } 34 | -------------------------------------------------------------------------------- /go-kit/v11/user_agent/src/middleware_tracer.go: -------------------------------------------------------------------------------- 1 | package src 2 | 3 | import ( 4 | "context" 5 | "github.com/opentracing/opentracing-go" 6 | "github.com/opentracing/opentracing-go/ext" 7 | ) 8 | 9 | type tracerMiddlewareServer struct { 10 | next Service 11 | tracer opentracing.Tracer 12 | } 13 | 14 | func NewTracerMiddlewareServer(tracer opentracing.Tracer) NewMiddlewareServer { 15 | return func(service Service) Service { 16 | return tracerMiddlewareServer{ 17 | next: service, 18 | tracer: tracer, 19 | } 20 | } 21 | } 22 | 23 | func (l tracerMiddlewareServer) Login(ctx context.Context, in Login) (out LoginAck, err error) { 24 | span, ctxContext := opentracing.StartSpanFromContextWithTracer(ctx, l.tracer, "service", opentracing.Tag{ 25 | Key: string(ext.Component), 26 | Value: "NewTracerServerMiddleware", 27 | }) 28 | defer func() { 29 | span.LogKV("account", in.Account, "password", in.Password) 30 | span.Finish() 31 | }() 32 | out, err = l.next.Login(ctxContext, in) 33 | return 34 | } 35 | -------------------------------------------------------------------------------- /go-kit/v11/utils/jwt_test.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestCreateJwtToken(t *testing.T) { 8 | jwtToken, err := CreateJwtToken("hwholiday", 2) 9 | if err != nil { 10 | t.Error(err) 11 | } 12 | t.Log(jwtToken) 13 | jwtInfo, err := ParseToken(jwtToken) 14 | if err != nil { 15 | t.Error(err) 16 | } 17 | t.Log(jwtInfo) 18 | } 19 | -------------------------------------------------------------------------------- /go-kit/v11/utils/log.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "github.com/hwholiday/learning_tools/all_packaged_library/logtool" 5 | "go.uber.org/zap" 6 | ) 7 | 8 | const ContextReqUUid = "req_uuid" 9 | 10 | var logger *zap.Logger 11 | 12 | func NewLoggerServer() { 13 | logger = logtool.NewLogger( 14 | logtool.SetAppName("go-kit-v11-server"), 15 | logtool.SetDevelopment(true), 16 | logtool.SetLevel(zap.DebugLevel), 17 | ) 18 | } 19 | 20 | func GetLogger() *zap.Logger { 21 | return logger 22 | } 23 | -------------------------------------------------------------------------------- /go-kit/v11/utils/zap_log_error_handler.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "go.uber.org/zap" 7 | ) 8 | 9 | type LogErrorHandler struct { 10 | logger *zap.Logger 11 | } 12 | 13 | func NewZapLogErrorHandler(logger *zap.Logger) *LogErrorHandler { 14 | return &LogErrorHandler{ 15 | logger: logger, 16 | } 17 | } 18 | 19 | func (h *LogErrorHandler) Handle(ctx context.Context, err error) { 20 | h.logger.Warn(fmt.Sprint(ctx.Value("req_uuid")), zap.Error(err)) 21 | } 22 | -------------------------------------------------------------------------------- /go-kit/v2/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/hwholiday/learning_tools/go-kit/v2/utils" 5 | "github.com/hwholiday/learning_tools/go-kit/v2/v2_endpoint" 6 | "github.com/hwholiday/learning_tools/go-kit/v2/v2_service" 7 | "github.com/hwholiday/learning_tools/go-kit/v2/v2_transport" 8 | "net/http" 9 | ) 10 | 11 | func main() { 12 | utils.NewLoggerServer() 13 | server := v2_service.NewService(utils.GetLogger()) 14 | endpoints := v2_endpoint.NewEndPointServer(server, utils.GetLogger()) 15 | httpHandler := v2_transport.NewHttpHandler(endpoints, utils.GetLogger()) 16 | utils.GetLogger().Info("server run 0.0.0.0:8888") 17 | _ = http.ListenAndServe("0.0.0.0:8888", httpHandler) 18 | 19 | } 20 | -------------------------------------------------------------------------------- /go-kit/v2/utils/log.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "github.com/hwholiday/learning_tools/all_packaged_library/logtool" 5 | "go.uber.org/zap" 6 | ) 7 | 8 | var logger *zap.Logger 9 | 10 | func NewLoggerServer() { 11 | logger = logtool.NewLogger( 12 | logtool.SetAppName("go-kit"), 13 | logtool.SetDevelopment(true), 14 | logtool.SetLevel(zap.DebugLevel), 15 | ) 16 | } 17 | 18 | func GetLogger() *zap.Logger { 19 | return logger 20 | } 21 | -------------------------------------------------------------------------------- /go-kit/v2/v2_endpoint/endpoint.go: -------------------------------------------------------------------------------- 1 | package v2_endpoint 2 | 3 | import ( 4 | "context" 5 | "github.com/go-kit/kit/endpoint" 6 | "github.com/hwholiday/learning_tools/go-kit/v2/v2_service" 7 | "go.uber.org/zap" 8 | ) 9 | 10 | type EndPointServer struct { 11 | AddEndPoint endpoint.Endpoint 12 | } 13 | 14 | func NewEndPointServer(svc v2_service.Service, log *zap.Logger) EndPointServer { 15 | var addEndPoint endpoint.Endpoint 16 | { 17 | addEndPoint = MakeAddEndPoint(svc) 18 | addEndPoint = LoggingMiddleware(log)(addEndPoint) 19 | } 20 | return EndPointServer{AddEndPoint: addEndPoint} 21 | } 22 | 23 | func (s EndPointServer) Add(ctx context.Context, in v2_service.Add) v2_service.AddAck { 24 | res, _ := s.AddEndPoint(ctx, in) 25 | return res.(v2_service.AddAck) 26 | } 27 | 28 | func MakeAddEndPoint(s v2_service.Service) endpoint.Endpoint { 29 | return func(ctx context.Context, request interface{}) (response interface{}, err error) { 30 | req := request.(v2_service.Add) 31 | res := s.TestAdd(ctx, req) 32 | return res, nil 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /go-kit/v2/v2_endpoint/middleware.go: -------------------------------------------------------------------------------- 1 | package v2_endpoint 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "github.com/go-kit/kit/endpoint" 7 | "github.com/hwholiday/learning_tools/go-kit/v2/v2_service" 8 | "go.uber.org/zap" 9 | "time" 10 | ) 11 | 12 | func LoggingMiddleware(logger *zap.Logger) endpoint.Middleware { 13 | return func(next endpoint.Endpoint) endpoint.Endpoint { 14 | return func(ctx context.Context, request interface{}) (response interface{}, err error) { 15 | defer func(begin time.Time) { 16 | logger.Debug(fmt.Sprint(ctx.Value(v2_service.ContextReqUUid)), zap.Any("调用 v2_endpoint LoggingMiddleware", "处理完请求"), zap.Any("耗时毫秒", time.Since(begin).Milliseconds())) 17 | }(time.Now()) 18 | return next(ctx, request) 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /go-kit/v2/v2_service/middleware.go: -------------------------------------------------------------------------------- 1 | package v2_service 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "go.uber.org/zap" 7 | ) 8 | 9 | const ContextReqUUid = "req_uuid" 10 | 11 | type NewMiddlewareServer func(Service) Service 12 | 13 | type logMiddlewareServer struct { 14 | logger *zap.Logger 15 | next Service 16 | } 17 | 18 | func NewLogMiddlewareServer(log *zap.Logger) NewMiddlewareServer { 19 | return func(service Service) Service { 20 | return logMiddlewareServer{ 21 | logger: log, 22 | next: service, 23 | } 24 | } 25 | } 26 | 27 | func (l logMiddlewareServer) TestAdd(ctx context.Context, in Add) (out AddAck) { 28 | defer func() { 29 | l.logger.Debug(fmt.Sprint(ctx.Value(ContextReqUUid)), zap.Any("调用 v2_service logMiddlewareServer", "TestAdd"), zap.Any("req", in), zap.Any("res", out)) 30 | }() 31 | out = l.next.TestAdd(ctx, in) 32 | return out 33 | } 34 | -------------------------------------------------------------------------------- /go-kit/v2/v2_service/model.go: -------------------------------------------------------------------------------- 1 | package v2_service 2 | 3 | type Add struct { 4 | A int `json:"a"` 5 | B int `json:"b"` 6 | } 7 | 8 | type AddAck struct { 9 | Res int `json:"res"` 10 | } 11 | -------------------------------------------------------------------------------- /go-kit/v2/v2_service/service.go: -------------------------------------------------------------------------------- 1 | package v2_service 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "go.uber.org/zap" 7 | "time" 8 | ) 9 | 10 | type Service interface { 11 | TestAdd(ctx context.Context, in Add) AddAck 12 | } 13 | 14 | type baseServer struct { 15 | logger *zap.Logger 16 | } 17 | 18 | func NewService(log *zap.Logger) Service { 19 | var server Service 20 | server = &baseServer{log} 21 | server = NewLogMiddlewareServer(log)(server) 22 | return server 23 | } 24 | 25 | func (s baseServer) TestAdd(ctx context.Context, in Add) AddAck { 26 | //模拟耗时 27 | time.Sleep(time.Millisecond * 2) 28 | s.logger.Debug(fmt.Sprint(ctx.Value(ContextReqUUid)), zap.Any("调用 v2_service Service", "TestAdd 处理请求")) 29 | ack := AddAck{Res: in.A + in.B} 30 | s.logger.Debug(fmt.Sprint(ctx.Value(ContextReqUUid)), zap.Any("调用 v2_service Service", "TestAdd 处理请求"), zap.Any("处理返回值", ack)) 31 | return ack 32 | } 33 | -------------------------------------------------------------------------------- /go-kit/v2/v2_transport/ZapLogErrorHandler.go: -------------------------------------------------------------------------------- 1 | package v2_transport 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "github.com/hwholiday/learning_tools/go-kit/v2/v2_service" 7 | "go.uber.org/zap" 8 | ) 9 | 10 | type LogErrorHandler struct { 11 | logger *zap.Logger 12 | } 13 | 14 | func NewZapLogErrorHandler(logger *zap.Logger) *LogErrorHandler { 15 | return &LogErrorHandler{ 16 | logger: logger, 17 | } 18 | } 19 | 20 | func (h *LogErrorHandler) Handle(ctx context.Context, err error) { 21 | h.logger.Warn(fmt.Sprint(ctx.Value(v2_service.ContextReqUUid), zap.Error(err))) 22 | } 23 | -------------------------------------------------------------------------------- /go-kit/v3/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/hwholiday/learning_tools/go-kit/v3/utils" 5 | "github.com/hwholiday/learning_tools/go-kit/v3/v3_endpoint" 6 | "github.com/hwholiday/learning_tools/go-kit/v3/v3_service" 7 | "github.com/hwholiday/learning_tools/go-kit/v3/v3_transport" 8 | "net/http" 9 | ) 10 | 11 | func main() { 12 | utils.NewLoggerServer() 13 | server := v3_service.NewService(utils.GetLogger()) 14 | endpoints := v3_endpoint.NewEndPointServer(server, utils.GetLogger()) 15 | httpHandler := v3_transport.NewHttpHandler(endpoints, utils.GetLogger()) 16 | utils.GetLogger().Info("server run 0.0.0.0:8888") 17 | _ = http.ListenAndServe("0.0.0.0:8888", httpHandler) 18 | 19 | } 20 | -------------------------------------------------------------------------------- /go-kit/v3/utils/jwt_test.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestCreateJwtToken(t *testing.T) { 8 | jwtToken, err := CreateJwtToken("hwholiday", 2) 9 | if err != nil { 10 | t.Error(err) 11 | } 12 | t.Log(jwtToken) 13 | jwtInfo, err := ParseToken(jwtToken) 14 | if err != nil { 15 | t.Error(err) 16 | } 17 | t.Log(jwtInfo) 18 | } 19 | -------------------------------------------------------------------------------- /go-kit/v3/utils/log.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "github.com/hwholiday/learning_tools/all_packaged_library/logtool" 5 | "go.uber.org/zap" 6 | ) 7 | 8 | var logger *zap.Logger 9 | 10 | func NewLoggerServer() { 11 | logger = logtool.NewLogger( 12 | logtool.SetAppName("go-kit"), 13 | logtool.SetDevelopment(true), 14 | logtool.SetLevel(zap.DebugLevel), 15 | ) 16 | } 17 | 18 | func GetLogger() *zap.Logger { 19 | return logger 20 | } 21 | -------------------------------------------------------------------------------- /go-kit/v3/v3_service/model.go: -------------------------------------------------------------------------------- 1 | package v3_service 2 | 3 | type Add struct { 4 | A int `json:"a"` 5 | B int `json:"b"` 6 | } 7 | 8 | type AddAck struct { 9 | Res int `json:"res"` 10 | } 11 | 12 | type Login struct { 13 | Account string `json:"account"` 14 | Password string `json:"password"` 15 | } 16 | 17 | type LoginAck struct { 18 | Token string `json:"token"` 19 | } 20 | -------------------------------------------------------------------------------- /go-kit/v4/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/hwholiday/learning_tools/go-kit/v4/utils" 5 | "github.com/hwholiday/learning_tools/go-kit/v4/v4_endpoint" 6 | "github.com/hwholiday/learning_tools/go-kit/v4/v4_service" 7 | "github.com/hwholiday/learning_tools/go-kit/v4/v4_transport" 8 | "go.uber.org/ratelimit" 9 | "golang.org/x/time/rate" 10 | "net/http" 11 | ) 12 | 13 | func main() { 14 | utils.NewLoggerServer() 15 | golangLimit := rate.NewLimiter(10, 1) //每秒产生10个令牌,令牌桶的可以装1个令牌 16 | uberLimit := ratelimit.New(1) //一秒请求一次 17 | server := v4_service.NewService(utils.GetLogger()) 18 | endpoints := v4_endpoint.NewEndPointServer(server, utils.GetLogger(), golangLimit, uberLimit) 19 | httpHandler := v4_transport.NewHttpHandler(endpoints, utils.GetLogger()) 20 | utils.GetLogger().Info("server run 0.0.0.0:8888") 21 | _ = http.ListenAndServe("0.0.0.0:8888", httpHandler) 22 | 23 | } 24 | -------------------------------------------------------------------------------- /go-kit/v4/utils/jwt_test.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestCreateJwtToken(t *testing.T) { 8 | jwtToken, err := CreateJwtToken("hwholiday", 2) 9 | if err != nil { 10 | t.Error(err) 11 | } 12 | t.Log(jwtToken) 13 | jwtInfo, err := ParseToken(jwtToken) 14 | if err != nil { 15 | t.Error(err) 16 | } 17 | t.Log(jwtInfo) 18 | } 19 | -------------------------------------------------------------------------------- /go-kit/v4/utils/log.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "github.com/hwholiday/learning_tools/all_packaged_library/logtool" 5 | "go.uber.org/zap" 6 | ) 7 | 8 | var logger *zap.Logger 9 | 10 | func NewLoggerServer() { 11 | logger = logtool.NewLogger( 12 | logtool.SetAppName("go-kit"), 13 | logtool.SetDevelopment(true), 14 | logtool.SetLevel(zap.DebugLevel), 15 | ) 16 | } 17 | 18 | func GetLogger() *zap.Logger { 19 | return logger 20 | } 21 | -------------------------------------------------------------------------------- /go-kit/v4/v4_service/model.go: -------------------------------------------------------------------------------- 1 | package v4_service 2 | 3 | type Add struct { 4 | A int `json:"a"` 5 | B int `json:"b"` 6 | } 7 | 8 | type AddAck struct { 9 | Res int `json:"res"` 10 | } 11 | 12 | type Login struct { 13 | Account string `json:"account"` 14 | Password string `json:"password"` 15 | } 16 | 17 | type LoginAck struct { 18 | Token string `json:"token"` 19 | } 20 | -------------------------------------------------------------------------------- /go-kit/v5/utils/jwt_test.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestCreateJwtToken(t *testing.T) { 8 | jwtToken, err := CreateJwtToken("hwholiday", 2) 9 | if err != nil { 10 | t.Error(err) 11 | } 12 | t.Log(jwtToken) 13 | jwtInfo, err := ParseToken(jwtToken) 14 | if err != nil { 15 | t.Error(err) 16 | } 17 | t.Log(jwtInfo) 18 | } 19 | -------------------------------------------------------------------------------- /go-kit/v5/utils/log.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "github.com/hwholiday/learning_tools/all_packaged_library/logtool" 5 | "go.uber.org/zap" 6 | ) 7 | 8 | var logger *zap.Logger 9 | 10 | func NewLoggerServer() { 11 | logger = logtool.NewLogger( 12 | logtool.SetAppName("go-kit"), 13 | logtool.SetDevelopment(true), 14 | logtool.SetLevel(zap.DebugLevel), 15 | ) 16 | } 17 | 18 | func GetLogger() *zap.Logger { 19 | return logger 20 | } 21 | -------------------------------------------------------------------------------- /go-kit/v5/v5_user/pb/make.sh: -------------------------------------------------------------------------------- 1 | protoc --go_out=plugins=grpc:. *.proto -------------------------------------------------------------------------------- /go-kit/v5/v5_user/pb/service.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package pb; 3 | import "user.proto"; 4 | service User { 5 | rpc RpcUserLogin (Login) returns (LoginAck) { 6 | } 7 | } -------------------------------------------------------------------------------- /go-kit/v5/v5_user/pb/user.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package pb; 3 | 4 | message Login { 5 | string Account = 1; 6 | string Password = 2; 7 | } 8 | 9 | message LoginAck { 10 | string Token = 1; 11 | } -------------------------------------------------------------------------------- /go-kit/v5/v5_user/v5_service/middleware.go: -------------------------------------------------------------------------------- 1 | package v5_service 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "github.com/hwholiday/learning_tools/go-kit/v5/v5_user/pb" 7 | "go.uber.org/zap" 8 | ) 9 | 10 | const ContextReqUUid = "req_uuid" 11 | 12 | type NewMiddlewareServer func(Service) Service 13 | 14 | type logMiddlewareServer struct { 15 | logger *zap.Logger 16 | next Service 17 | } 18 | 19 | func NewLogMiddlewareServer(log *zap.Logger) NewMiddlewareServer { 20 | return func(service Service) Service { 21 | return logMiddlewareServer{ 22 | logger: log, 23 | next: service, 24 | } 25 | } 26 | } 27 | 28 | func (l logMiddlewareServer) Login(ctx context.Context, in *pb.Login) (out *pb.LoginAck, err error) { 29 | defer func() { 30 | l.logger.Debug(fmt.Sprint(ctx.Value(ContextReqUUid)), zap.Any("调用 Login logMiddlewareServer", "Login"), zap.Any("req", in), zap.Any("res", out), zap.Any("err", err)) 31 | }() 32 | out, err = l.next.Login(ctx, in) 33 | return 34 | } 35 | -------------------------------------------------------------------------------- /go-kit/v5/v5_user/v5_transport/ZapLogErrorHandler.go: -------------------------------------------------------------------------------- 1 | package v5_transport 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "github.com/hwholiday/learning_tools/go-kit/v5/v5_user/v5_service" 7 | "go.uber.org/zap" 8 | ) 9 | 10 | type LogErrorHandler struct { 11 | logger *zap.Logger 12 | } 13 | 14 | func NewZapLogErrorHandler(logger *zap.Logger) *LogErrorHandler { 15 | return &LogErrorHandler{ 16 | logger: logger, 17 | } 18 | } 19 | 20 | func (h *LogErrorHandler) Handle(ctx context.Context, err error) { 21 | h.logger.Warn(fmt.Sprint(ctx.Value(v5_service.ContextReqUUid)), zap.Error(err)) 22 | } 23 | -------------------------------------------------------------------------------- /go-kit/v6/user_agent/pb/make.sh: -------------------------------------------------------------------------------- 1 | protoc --go_out=plugins=grpc:. *.proto -------------------------------------------------------------------------------- /go-kit/v6/user_agent/pb/service.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package pb; 3 | import "user.proto"; 4 | service User { 5 | rpc RpcUserLogin (Login) returns (LoginAck) { 6 | } 7 | } -------------------------------------------------------------------------------- /go-kit/v6/user_agent/pb/user.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package pb; 3 | 4 | message Login { 5 | string Account = 1; 6 | string Password = 2; 7 | } 8 | 9 | message LoginAck { 10 | string Token = 1; 11 | } -------------------------------------------------------------------------------- /go-kit/v6/user_agent/src/endpoint.go: -------------------------------------------------------------------------------- 1 | package src 2 | 3 | import ( 4 | "context" 5 | "github.com/go-kit/kit/endpoint" 6 | "github.com/hwholiday/learning_tools/go-kit/v6/user_agent/pb" 7 | "golang.org/x/time/rate" 8 | ) 9 | 10 | type EndPointServer struct { 11 | LoginEndPoint endpoint.Endpoint 12 | } 13 | 14 | func NewEndPointServer(svc Service, limit *rate.Limiter) EndPointServer { 15 | var loginEndPoint endpoint.Endpoint 16 | { 17 | loginEndPoint = MakeLoginEndPoint(svc) 18 | loginEndPoint = NewGolangRateAllowMiddleware(limit)(loginEndPoint) 19 | } 20 | return EndPointServer{LoginEndPoint: loginEndPoint} 21 | } 22 | 23 | func (s EndPointServer) Login(ctx context.Context, in *pb.Login) (*pb.LoginAck, error) { 24 | res, err := s.LoginEndPoint(ctx, in) 25 | if err != nil { 26 | return nil, err 27 | } 28 | return res.(*pb.LoginAck), nil 29 | } 30 | 31 | func MakeLoginEndPoint(s Service) endpoint.Endpoint { 32 | return func(ctx context.Context, request interface{}) (response interface{}, err error) { 33 | req := request.(*pb.Login) 34 | return s.Login(ctx, req) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /go-kit/v6/user_agent/src/middleware_endpoint.go: -------------------------------------------------------------------------------- 1 | package src 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "github.com/go-kit/kit/endpoint" 7 | "golang.org/x/time/rate" 8 | ) 9 | 10 | func NewGolangRateAllowMiddleware(limit *rate.Limiter) endpoint.Middleware { 11 | return func(next endpoint.Endpoint) endpoint.Endpoint { 12 | return func(ctx context.Context, request interface{}) (response interface{}, err error) { 13 | if !limit.Allow() { 14 | return "", errors.New("limit req Allow") 15 | } 16 | return next(ctx, request) 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /go-kit/v6/user_agent/src/middleware_server.go: -------------------------------------------------------------------------------- 1 | package src 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "github.com/hwholiday/learning_tools/go-kit/v6/user_agent/pb" 7 | "go.uber.org/zap" 8 | "time" 9 | ) 10 | 11 | const ContextReqUUid = "req_uuid" 12 | 13 | type NewMiddlewareServer func(Service) Service 14 | 15 | type logMiddlewareServer struct { 16 | logger *zap.Logger 17 | next Service 18 | } 19 | 20 | func NewLogMiddlewareServer(log *zap.Logger) NewMiddlewareServer { 21 | return func(service Service) Service { 22 | return logMiddlewareServer{ 23 | logger: log, 24 | next: service, 25 | } 26 | } 27 | } 28 | 29 | func (l logMiddlewareServer) Login(ctx context.Context, in *pb.Login) (out *pb.LoginAck, err error) { 30 | defer func(start time.Time) { 31 | l.logger.Debug(fmt.Sprint(ctx.Value(ContextReqUUid)), zap.Any("调用 Login logMiddlewareServer", "Login"), zap.Any("req", in), zap.Any("res", out), zap.Any("time", time.Since(start)), zap.Any("err", err)) 32 | }(time.Now()) 33 | out, err = l.next.Login(ctx, in) 34 | return 35 | } 36 | -------------------------------------------------------------------------------- /go-kit/v6/user_agent/src/service.go: -------------------------------------------------------------------------------- 1 | package src 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "github.com/hwholiday/learning_tools/go-kit/v6/user_agent/pb" 7 | "github.com/hwholiday/learning_tools/go-kit/v6/utils" 8 | "go.uber.org/zap" 9 | ) 10 | 11 | type Service interface { 12 | Login(ctx context.Context, in *pb.Login) (ack *pb.LoginAck, err error) 13 | } 14 | 15 | type baseServer struct { 16 | logger *zap.Logger 17 | } 18 | 19 | func NewService(log *zap.Logger) Service { 20 | var server Service 21 | server = &baseServer{log} 22 | server = NewLogMiddlewareServer(log)(server) 23 | return server 24 | } 25 | 26 | func (s baseServer) Login(ctx context.Context, in *pb.Login) (ack *pb.LoginAck, err error) { 27 | if in.Account != "hwholiday" || in.Password != "123456" { 28 | err = errors.New("用户信息错误") 29 | return 30 | } 31 | ack = &pb.LoginAck{} 32 | ack.Token, err = utils.CreateJwtToken(in.Account, 1) 33 | return 34 | } 35 | -------------------------------------------------------------------------------- /go-kit/v6/utils/jwt_test.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestCreateJwtToken(t *testing.T) { 8 | jwtToken, err := CreateJwtToken("hwholiday", 2) 9 | if err != nil { 10 | t.Error(err) 11 | } 12 | t.Log(jwtToken) 13 | jwtInfo, err := ParseToken(jwtToken) 14 | if err != nil { 15 | t.Error(err) 16 | } 17 | t.Log(jwtInfo) 18 | } 19 | -------------------------------------------------------------------------------- /go-kit/v6/utils/log.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "github.com/hwholiday/learning_tools/all_packaged_library/logtool" 5 | "go.uber.org/zap" 6 | ) 7 | 8 | var logger *zap.Logger 9 | 10 | func NewLoggerServer() { 11 | logger = logtool.NewLogger( 12 | logtool.SetAppName("go-kit"), 13 | logtool.SetDevelopment(true), 14 | logtool.SetLevel(zap.DebugLevel), 15 | ) 16 | } 17 | 18 | func GetLogger() *zap.Logger { 19 | return logger 20 | } 21 | -------------------------------------------------------------------------------- /go-kit/v6/utils/zap_log_error_handler.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "go.uber.org/zap" 7 | ) 8 | 9 | type LogErrorHandler struct { 10 | logger *zap.Logger 11 | } 12 | 13 | func NewZapLogErrorHandler(logger *zap.Logger) *LogErrorHandler { 14 | return &LogErrorHandler{ 15 | logger: logger, 16 | } 17 | } 18 | 19 | func (h *LogErrorHandler) Handle(ctx context.Context, err error) { 20 | h.logger.Warn(fmt.Sprint(ctx.Value("req_uuid")), zap.Error(err)) 21 | } 22 | -------------------------------------------------------------------------------- /go-kit/v7/user_agent/pb/make.sh: -------------------------------------------------------------------------------- 1 | protoc --go_out=plugins=grpc:. *.proto -------------------------------------------------------------------------------- /go-kit/v7/user_agent/pb/service.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package pb; 3 | import "user.proto"; 4 | service User { 5 | rpc RpcUserLogin (Login) returns (LoginAck) { 6 | } 7 | } -------------------------------------------------------------------------------- /go-kit/v7/user_agent/pb/user.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package pb; 3 | 4 | message Login { 5 | string Account = 1; 6 | string Password = 2; 7 | } 8 | 9 | message LoginAck { 10 | string Token = 1; 11 | } -------------------------------------------------------------------------------- /go-kit/v7/user_agent/src/middleware_endpoint.go: -------------------------------------------------------------------------------- 1 | package src 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "github.com/go-kit/kit/endpoint" 7 | "golang.org/x/time/rate" 8 | ) 9 | 10 | func NewGolangRateAllowMiddleware(limit *rate.Limiter) endpoint.Middleware { 11 | return func(next endpoint.Endpoint) endpoint.Endpoint { 12 | return func(ctx context.Context, request interface{}) (response interface{}, err error) { 13 | if !limit.Allow() { 14 | return "", errors.New("limit req Allow") 15 | } 16 | return next(ctx, request) 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /go-kit/v7/user_agent/src/middleware_log.go: -------------------------------------------------------------------------------- 1 | package src 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "github.com/hwholiday/learning_tools/go-kit/v7/user_agent/pb" 7 | "go.uber.org/zap" 8 | "time" 9 | ) 10 | 11 | const ContextReqUUid = "req_uuid" 12 | 13 | type NewMiddlewareServer func(Service) Service 14 | 15 | type logMiddlewareServer struct { 16 | logger *zap.Logger 17 | next Service 18 | } 19 | 20 | func NewLogMiddlewareServer(log *zap.Logger) NewMiddlewareServer { 21 | return func(service Service) Service { 22 | return logMiddlewareServer{ 23 | logger: log, 24 | next: service, 25 | } 26 | } 27 | } 28 | 29 | func (l logMiddlewareServer) Login(ctx context.Context, in *pb.Login) (out *pb.LoginAck, err error) { 30 | defer func(start time.Time) { 31 | l.logger.Debug(fmt.Sprint(ctx.Value(ContextReqUUid)), zap.Any("调用 Login logMiddlewareServer", "Login"), zap.Any("req", in), zap.Any("res", out), zap.Any("time", time.Since(start)), zap.Any("err", err)) 32 | }(time.Now()) 33 | out, err = l.next.Login(ctx, in) 34 | return 35 | } 36 | -------------------------------------------------------------------------------- /go-kit/v7/user_agent/src/middleware_metrics.go: -------------------------------------------------------------------------------- 1 | package src 2 | 3 | import ( 4 | "context" 5 | "github.com/go-kit/kit/metrics" 6 | "github.com/hwholiday/learning_tools/go-kit/v7/user_agent/pb" 7 | "time" 8 | ) 9 | 10 | type metricsMiddlewareServer struct { 11 | next Service 12 | counter metrics.Counter 13 | histogram metrics.Histogram 14 | } 15 | 16 | func NewMetricsMiddlewareServer(counter metrics.Counter, histogram metrics.Histogram) NewMiddlewareServer { 17 | return func(service Service) Service { 18 | return metricsMiddlewareServer{ 19 | next: service, 20 | counter: counter, 21 | histogram: histogram, 22 | } 23 | } 24 | } 25 | 26 | func (l metricsMiddlewareServer) Login(ctx context.Context, in *pb.Login) (out *pb.LoginAck, err error) { 27 | defer func(start time.Time) { 28 | method := []string{"method", "login"} 29 | l.counter.With(method...).Add(1) 30 | l.histogram.With(method...).Observe(time.Since(start).Seconds()) 31 | }(time.Now()) 32 | out, err = l.next.Login(ctx, in) 33 | return 34 | } 35 | -------------------------------------------------------------------------------- /go-kit/v7/utils/jwt_test.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestCreateJwtToken(t *testing.T) { 8 | jwtToken, err := CreateJwtToken("hwholiday", 2) 9 | if err != nil { 10 | t.Error(err) 11 | } 12 | t.Log(jwtToken) 13 | jwtInfo, err := ParseToken(jwtToken) 14 | if err != nil { 15 | t.Error(err) 16 | } 17 | t.Log(jwtInfo) 18 | } 19 | -------------------------------------------------------------------------------- /go-kit/v7/utils/log.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "github.com/hwholiday/learning_tools/all_packaged_library/logtool" 5 | "go.uber.org/zap" 6 | ) 7 | 8 | var logger *zap.Logger 9 | 10 | func NewLoggerServer() { 11 | logger = logtool.NewLogger( 12 | logtool.SetAppName("go-kit"), 13 | logtool.SetDevelopment(true), 14 | logtool.SetLevel(zap.DebugLevel), 15 | ) 16 | } 17 | 18 | func GetLogger() *zap.Logger { 19 | return logger 20 | } 21 | -------------------------------------------------------------------------------- /go-kit/v7/utils/zap_log_error_handler.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "go.uber.org/zap" 7 | ) 8 | 9 | type LogErrorHandler struct { 10 | logger *zap.Logger 11 | } 12 | 13 | func NewZapLogErrorHandler(logger *zap.Logger) *LogErrorHandler { 14 | return &LogErrorHandler{ 15 | logger: logger, 16 | } 17 | } 18 | 19 | func (h *LogErrorHandler) Handle(ctx context.Context, err error) { 20 | h.logger.Warn(fmt.Sprint(ctx.Value("req_uuid")), zap.Error(err)) 21 | } 22 | -------------------------------------------------------------------------------- /go-kit/v8/user_agent/pb/make.sh: -------------------------------------------------------------------------------- 1 | protoc --go_out=plugins=grpc:. *.proto -------------------------------------------------------------------------------- /go-kit/v8/user_agent/pb/service.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package pb; 3 | import "user.proto"; 4 | service User { 5 | rpc RpcUserLogin (Login) returns (LoginAck) { 6 | } 7 | } -------------------------------------------------------------------------------- /go-kit/v8/user_agent/pb/user.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package pb; 3 | 4 | message Login { 5 | string Account = 1; 6 | string Password = 2; 7 | } 8 | 9 | message LoginAck { 10 | string Token = 1; 11 | } -------------------------------------------------------------------------------- /go-kit/v8/user_agent/src/middleware_endpoint.go: -------------------------------------------------------------------------------- 1 | package src 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "github.com/go-kit/kit/endpoint" 7 | "golang.org/x/time/rate" 8 | ) 9 | 10 | func NewGolangRateAllowMiddleware(limit *rate.Limiter) endpoint.Middleware { 11 | return func(next endpoint.Endpoint) endpoint.Endpoint { 12 | return func(ctx context.Context, request interface{}) (response interface{}, err error) { 13 | if !limit.Allow() { 14 | return "", errors.New("limit req Allow") 15 | } 16 | return next(ctx, request) 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /go-kit/v8/user_agent/src/middleware_log.go: -------------------------------------------------------------------------------- 1 | package src 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "github.com/hwholiday/learning_tools/go-kit/v8/user_agent/pb" 7 | "go.uber.org/zap" 8 | "time" 9 | ) 10 | 11 | const ContextReqUUid = "req_uuid" 12 | 13 | type NewMiddlewareServer func(Service) Service 14 | 15 | type logMiddlewareServer struct { 16 | logger *zap.Logger 17 | next Service 18 | } 19 | 20 | func NewLogMiddlewareServer(log *zap.Logger) NewMiddlewareServer { 21 | return func(service Service) Service { 22 | return logMiddlewareServer{ 23 | logger: log, 24 | next: service, 25 | } 26 | } 27 | } 28 | 29 | func (l logMiddlewareServer) Login(ctx context.Context, in *pb.Login) (out *pb.LoginAck, err error) { 30 | defer func(start time.Time) { 31 | l.logger.Debug(fmt.Sprint(ctx.Value(ContextReqUUid)), zap.Any("调用 Login logMiddlewareServer", "Login"), zap.Any("req", in), zap.Any("res", out), zap.Any("time", time.Since(start)), zap.Any("err", err)) 32 | }(time.Now()) 33 | out, err = l.next.Login(ctx, in) 34 | return 35 | } 36 | -------------------------------------------------------------------------------- /go-kit/v8/user_agent/src/middleware_metrics.go: -------------------------------------------------------------------------------- 1 | package src 2 | 3 | import ( 4 | "context" 5 | "github.com/go-kit/kit/metrics" 6 | "github.com/hwholiday/learning_tools/go-kit/v8/user_agent/pb" 7 | "time" 8 | ) 9 | 10 | type metricsMiddlewareServer struct { 11 | next Service 12 | counter metrics.Counter 13 | histogram metrics.Histogram 14 | } 15 | 16 | func NewMetricsMiddlewareServer(counter metrics.Counter, histogram metrics.Histogram) NewMiddlewareServer { 17 | return func(service Service) Service { 18 | return metricsMiddlewareServer{ 19 | next: service, 20 | counter: counter, 21 | histogram: histogram, 22 | } 23 | } 24 | } 25 | 26 | func (l metricsMiddlewareServer) Login(ctx context.Context, in *pb.Login) (out *pb.LoginAck, err error) { 27 | defer func(start time.Time) { 28 | method := []string{"method", "login"} 29 | l.counter.With(method...).Add(1) 30 | l.histogram.With(method...).Observe(time.Since(start).Seconds()) 31 | }(time.Now()) 32 | out, err = l.next.Login(ctx, in) 33 | return 34 | } 35 | -------------------------------------------------------------------------------- /go-kit/v8/utils/jwt_test.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestCreateJwtToken(t *testing.T) { 8 | jwtToken, err := CreateJwtToken("hwholiday", 2) 9 | if err != nil { 10 | t.Error(err) 11 | } 12 | t.Log(jwtToken) 13 | jwtInfo, err := ParseToken(jwtToken) 14 | if err != nil { 15 | t.Error(err) 16 | } 17 | t.Log(jwtInfo) 18 | } 19 | -------------------------------------------------------------------------------- /go-kit/v8/utils/log.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "github.com/hwholiday/learning_tools/all_packaged_library/logtool" 5 | "go.uber.org/zap" 6 | ) 7 | 8 | var logger *zap.Logger 9 | 10 | func NewLoggerServer() { 11 | logger = logtool.NewLogger( 12 | logtool.SetAppName("go-kit"), 13 | logtool.SetDevelopment(true), 14 | logtool.SetLevel(zap.DebugLevel), 15 | ) 16 | } 17 | 18 | func GetLogger() *zap.Logger { 19 | return logger 20 | } 21 | -------------------------------------------------------------------------------- /go-kit/v8/utils/zap_log_error_handler.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "go.uber.org/zap" 7 | ) 8 | 9 | type LogErrorHandler struct { 10 | logger *zap.Logger 11 | } 12 | 13 | func NewZapLogErrorHandler(logger *zap.Logger) *LogErrorHandler { 14 | return &LogErrorHandler{ 15 | logger: logger, 16 | } 17 | } 18 | 19 | func (h *LogErrorHandler) Handle(ctx context.Context, err error) { 20 | h.logger.Warn(fmt.Sprint(ctx.Value("req_uuid")), zap.Error(err)) 21 | } 22 | -------------------------------------------------------------------------------- /go-kit/v9/user_agent/build.sh: -------------------------------------------------------------------------------- 1 | CGO_ENABLED=0 GOOS=linux go build -a -ldflags '-extldflags "-static"' -o user_agent . 2 | -------------------------------------------------------------------------------- /go-kit/v9/user_agent/pb/make.sh: -------------------------------------------------------------------------------- 1 | protoc --go_out=plugins=grpc:. *.proto -------------------------------------------------------------------------------- /go-kit/v9/user_agent/pb/service.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package pb; 3 | import "user.proto"; 4 | service User { 5 | rpc RpcUserLogin (Login) returns (LoginAck) { 6 | } 7 | } -------------------------------------------------------------------------------- /go-kit/v9/user_agent/pb/user.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package pb; 3 | 4 | message Login { 5 | string Account = 1; 6 | string Password = 2; 7 | } 8 | 9 | message LoginAck { 10 | string Token = 1; 11 | } -------------------------------------------------------------------------------- /go-kit/v9/user_agent/src/middleware_log.go: -------------------------------------------------------------------------------- 1 | package src 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "github.com/hwholiday/learning_tools/go-kit/v9/user_agent/pb" 7 | "github.com/hwholiday/learning_tools/go-kit/v9/utils" 8 | "go.uber.org/zap" 9 | "time" 10 | ) 11 | 12 | type NewMiddlewareServer func(Service) Service 13 | 14 | type logMiddlewareServer struct { 15 | logger *zap.Logger 16 | next Service 17 | } 18 | 19 | func NewLogMiddlewareServer(log *zap.Logger) NewMiddlewareServer { 20 | return func(service Service) Service { 21 | return logMiddlewareServer{ 22 | logger: log, 23 | next: service, 24 | } 25 | } 26 | } 27 | 28 | func (l logMiddlewareServer) Login(ctx context.Context, in *pb.Login) (out *pb.LoginAck, err error) { 29 | defer func(start time.Time) { 30 | l.logger.Debug(fmt.Sprint(ctx.Value(utils.ContextReqUUid)), zap.Any("调用 Login logMiddlewareServer", "Login"), zap.Any("req", in), zap.Any("res", out), zap.Any("time", time.Since(start)), zap.Any("err", err)) 31 | }(time.Now()) 32 | out, err = l.next.Login(ctx, in) 33 | return 34 | } 35 | -------------------------------------------------------------------------------- /go-kit/v9/user_agent/src/middleware_metrics.go: -------------------------------------------------------------------------------- 1 | package src 2 | 3 | import ( 4 | "context" 5 | "github.com/go-kit/kit/metrics" 6 | "github.com/hwholiday/learning_tools/go-kit/v9/user_agent/pb" 7 | "time" 8 | ) 9 | 10 | type metricsMiddlewareServer struct { 11 | next Service 12 | counter metrics.Counter 13 | histogram metrics.Histogram 14 | } 15 | 16 | func NewMetricsMiddlewareServer(counter metrics.Counter, histogram metrics.Histogram) NewMiddlewareServer { 17 | return func(service Service) Service { 18 | return metricsMiddlewareServer{ 19 | next: service, 20 | counter: counter, 21 | histogram: histogram, 22 | } 23 | } 24 | } 25 | 26 | func (l metricsMiddlewareServer) Login(ctx context.Context, in *pb.Login) (out *pb.LoginAck, err error) { 27 | defer func(start time.Time) { 28 | method := []string{"method", "login"} 29 | l.counter.With(method...).Add(1) 30 | l.histogram.With(method...).Observe(time.Since(start).Seconds()) 31 | }(time.Now()) 32 | out, err = l.next.Login(ctx, in) 33 | return 34 | } 35 | -------------------------------------------------------------------------------- /go-kit/v9/user_agent/src/middleware_tracer.go: -------------------------------------------------------------------------------- 1 | package src 2 | 3 | import ( 4 | "context" 5 | "github.com/hwholiday/learning_tools/go-kit/v9/user_agent/pb" 6 | "github.com/opentracing/opentracing-go" 7 | "github.com/opentracing/opentracing-go/ext" 8 | ) 9 | 10 | type tracerMiddlewareServer struct { 11 | next Service 12 | tracer opentracing.Tracer 13 | } 14 | 15 | func NewTracerMiddlewareServer(tracer opentracing.Tracer) NewMiddlewareServer { 16 | return func(service Service) Service { 17 | return tracerMiddlewareServer{ 18 | next: service, 19 | tracer: tracer, 20 | } 21 | } 22 | } 23 | 24 | func (l tracerMiddlewareServer) Login(ctx context.Context, in *pb.Login) (out *pb.LoginAck, err error) { 25 | span, ctxContext := opentracing.StartSpanFromContextWithTracer(ctx, l.tracer, "service", opentracing.Tag{ 26 | Key: string(ext.Component), 27 | Value: "NewTracerServerMiddleware", 28 | }) 29 | defer func() { 30 | span.LogKV("account", in.GetAccount(), "password", in.GetPassword()) 31 | span.Finish() 32 | }() 33 | out, err = l.next.Login(ctxContext, in) 34 | return 35 | } 36 | -------------------------------------------------------------------------------- /go-kit/v9/utils/jwt_test.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestCreateJwtToken(t *testing.T) { 8 | jwtToken, err := CreateJwtToken("hwholiday", 2) 9 | if err != nil { 10 | t.Error(err) 11 | } 12 | t.Log(jwtToken) 13 | jwtInfo, err := ParseToken(jwtToken) 14 | if err != nil { 15 | t.Error(err) 16 | } 17 | t.Log(jwtInfo) 18 | } 19 | -------------------------------------------------------------------------------- /go-kit/v9/utils/log.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "github.com/hwholiday/learning_tools/all_packaged_library/logtool" 5 | "go.uber.org/zap" 6 | ) 7 | 8 | const ContextReqUUid = "req_uuid" 9 | 10 | var logger *zap.Logger 11 | 12 | func NewLoggerServer() { 13 | logger = logtool.NewLogger( 14 | logtool.SetAppName("go-kit"), 15 | logtool.SetDevelopment(true), 16 | logtool.SetLevel(zap.DebugLevel), 17 | ) 18 | } 19 | 20 | func GetLogger() *zap.Logger { 21 | return logger 22 | } 23 | -------------------------------------------------------------------------------- /go-kit/v9/utils/zap_log_error_handler.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "go.uber.org/zap" 7 | ) 8 | 9 | type LogErrorHandler struct { 10 | logger *zap.Logger 11 | } 12 | 13 | func NewZapLogErrorHandler(logger *zap.Logger) *LogErrorHandler { 14 | return &LogErrorHandler{ 15 | logger: logger, 16 | } 17 | } 18 | 19 | func (h *LogErrorHandler) Handle(ctx context.Context, err error) { 20 | h.logger.Warn(fmt.Sprint(ctx.Value("req_uuid")), zap.Error(err)) 21 | } 22 | -------------------------------------------------------------------------------- /go-lua/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | lua "github.com/yuin/gopher-lua" 7 | ) 8 | 9 | var script = `function costPrice() 10 | if env.a=="aa" and env.b> 10 then 11 | return 2 12 | elseif env.a=="bb" and env.bindTime>1 and env.bindTime<9 then 13 | return 3 14 | end 15 | return 4 16 | end` 17 | 18 | func main() { 19 | L := lua.NewState() 20 | defer L.Close() 21 | env := L.NewTable() 22 | env.RawSetString("a", lua.LString("aa")) 23 | env.RawSetString("b", lua.LNumber(20)) 24 | L.SetGlobal("env", env) 25 | err := L.DoString(script) 26 | if err != nil { 27 | return 28 | } 29 | err = L.CallByParam(lua.P{ 30 | Fn: L.GetGlobal("costPrice"), 31 | NRet: 1, 32 | Protect: true, 33 | }) 34 | if err != nil { 35 | return 36 | } 37 | ret := L.Get(-1) 38 | L.Pop(1) 39 | fmt.Println("ret.String()", ret.String()) 40 | 41 | } 42 | -------------------------------------------------------------------------------- /go_push/gateway/ws_handle.go: -------------------------------------------------------------------------------- 1 | package gateway 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func (w *WsConnection) WsHandle() { 9 | var ( 10 | err error 11 | msg *WSMessage 12 | ) 13 | fmt.Println("开启链接: ", w.GetIp(), "ID", w.GetWsId()) 14 | GetRoomManage().AddConn(w) 15 | for { 16 | if msg, err = w.ReadMsg(); err != nil { 17 | w.CloseConn() 18 | return 19 | } 20 | //http://www.easyswoole.com/wstool.html 测试地址 21 | switch { 22 | case msg.Type == 1: //{"type":1,"data":"PING"},{"type":1,"data":"PONG"} 23 | _ = w.ws.SetReadDeadline(time.Now().Add(time.Second * 10)) 24 | _ = w.SendMsg(&WSMessage{Type: 1, Data: "PONG"}) 25 | default: 26 | fmt.Println("OTHER", msg.Type, msg.Data) 27 | 28 | } 29 | } 30 | 31 | } 32 | 33 | func (w *WsConnection) CloseConn() { 34 | w.close() 35 | GetRoomManage().DelConn(w) 36 | w.addRoom.Range(func(key, _ interface{}) bool { 37 | _ = GetRoomManage().LeaveRoom(key.(int), w.GetWsId()) 38 | w.addRoom.Delete(key) 39 | return true 40 | }) 41 | } 42 | -------------------------------------------------------------------------------- /go_push/logic/http_server.go: -------------------------------------------------------------------------------- 1 | package logic 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "time" 7 | ) 8 | 9 | func InitHttpServer() { 10 | //curl http://0.0.0.0:9999/push/all -X POST -d "val=test push&tag=3" 11 | //curl http://0.0.0.0:9999/push/room -X POST -d "val=test push&tag=3&id=1" 12 | //curl http://0.0.0.0:9999/room/join -X POST -d "id=1&wsId=3cc97117-aa4d-55bb-86db-a1d77e51283b" 13 | //curl http://0.0.0.0:9999/room/leave -X POST -d "id=1&wsId=3cc97117-aa4d-55bb-86db-a1d77e51283b" 14 | mux := http.NewServeMux() 15 | mux.HandleFunc("/push/all", HttpPushAll) 16 | mux.HandleFunc("/push/room", HttpPushRoom) 17 | mux.HandleFunc("/room/join", HttpRoomJoin) 18 | mux.HandleFunc("/room/leave", HttpRoomLeave) 19 | // HTTP服务 20 | server := http.Server{ 21 | Addr: "0.0.0.0:9999", 22 | ReadTimeout: time.Duration(10) * time.Millisecond, 23 | WriteTimeout: time.Duration(10) * time.Millisecond, 24 | Handler: mux, 25 | } 26 | fmt.Println("启动HTTP服务器成功 :", 9999) 27 | _ = server.ListenAndServe() 28 | } 29 | -------------------------------------------------------------------------------- /go_push/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/hwholiday/learning_tools/go_push/gateway" 5 | "github.com/hwholiday/learning_tools/go_push/logic" 6 | "os" 7 | "os/signal" 8 | "syscall" 9 | ) 10 | 11 | func main() { 12 | go gateway.InitWsServer() 13 | go logic.InitHttpServer() 14 | c := make(chan os.Signal, 1) 15 | signal.Notify(c, syscall.SIGINT, syscall.SIGTERM) 16 | <-c 17 | } 18 | -------------------------------------------------------------------------------- /goconvey/coverage.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | COVERAGE_NAME="coverage" 3 | PKG_LIST=$(go list ./... | grep -v /vendor/) 4 | 5 | go test -covermode=count -coverpkg="${PKG_LIST}" -coverprofile "${COVERAGE_NAME}.cov" 6 | 7 | if [ "$1" == "html" ]; then 8 | go tool cover -html="${COVERAGE_NAME}.cov" -o coverage.html 9 | fi 10 | 11 | if [ "$1" == "total" ]; then 12 | go tool cover -func="${COVERAGE_NAME}.cov" -o coverage.txt 13 | fi 14 | -------------------------------------------------------------------------------- /goconvey/goconvey.go: -------------------------------------------------------------------------------- 1 | package goconvey 2 | 3 | func Add(a, b int) int { 4 | return a + b 5 | } 6 | -------------------------------------------------------------------------------- /goconvey/goconvey_test.go: -------------------------------------------------------------------------------- 1 | package goconvey 2 | 3 | import ( 4 | . "github.com/smartystreets/goconvey/convey" 5 | "testing" 6 | ) 7 | 8 | func TestAdd(t *testing.T) { 9 | Convey("将两数相加", t, func(c C) { 10 | c.So(Add(1, 2), ShouldEqual, 3) 11 | }) 12 | } 13 | -------------------------------------------------------------------------------- /goconvey/goconvey_v1.go: -------------------------------------------------------------------------------- 1 | package goconvey 2 | 3 | func AddV1(a, b int) int { 4 | return a + b 5 | } 6 | -------------------------------------------------------------------------------- /goconvey/goconvey_v1_test.go: -------------------------------------------------------------------------------- 1 | package goconvey 2 | 3 | import ( 4 | . "github.com/smartystreets/goconvey/convey" 5 | "testing" 6 | ) 7 | 8 | func TestAddV1(t *testing.T) { 9 | Convey("将两数相加", t, func(c C) { 10 | c.So(AddV1(1, 2), ShouldEqual, 3) 11 | }) 12 | } 13 | -------------------------------------------------------------------------------- /grpc/bidirectional_streaming_rpc/proto/howie.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package proto; 3 | 4 | message Request { 5 | string input = 1; 6 | } 7 | 8 | message Response { 9 | string output = 1; 10 | } 11 | service ChatService { 12 | rpc Chat (stream Request) returns (stream Response) { 13 | } 14 | } -------------------------------------------------------------------------------- /grpc/bidirectional_streaming_rpc/proto/make.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | protoc --go_out=plugins=grpc:. *.proto -------------------------------------------------------------------------------- /grpc/protoc-gen-hw/examples/greeter/greeter.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | service Greeter { 4 | rpc Hello(Request) returns (Response) { 5 | } 6 | } 7 | 8 | message Request { 9 | string name = 1; 10 | } 11 | 12 | message Response { 13 | string msg = 1; 14 | } 15 | 16 | enum GameCommand { 17 | Nothing = 0; 18 | Hello = 1; 19 | PushExample = 2; 20 | } 21 | 22 | message Message { 23 | int64 PlayerId = 1; 24 | int32 Ops = 2; 25 | bytes Data = 3; 26 | } -------------------------------------------------------------------------------- /grpc/protoc-gen-hw/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/golang/protobuf/proto" 5 | "io/ioutil" 6 | "os" 7 | "protoc-gen-hw/generator" 8 | "protoc-gen-hw/plugin/hw" 9 | ) 10 | 11 | func main() { 12 | generator.RegisterPlugin(new(hw.Hw)) 13 | g := generator.New() 14 | data, err := ioutil.ReadAll(os.Stdin) 15 | if err != nil { 16 | g.Error(err, "reading input") 17 | } 18 | if err := proto.Unmarshal(data, g.Request); err != nil { 19 | g.Error(err, "parsing input proto") 20 | } 21 | if len(g.Request.FileToGenerate) == 0 { 22 | g.Fail("no files to generate") 23 | } 24 | g.CommandLineParameters(g.Request.GetParameter()) 25 | g.WrapTypes() 26 | g.SetPackageNames() 27 | g.BuildTypeNameMap() 28 | g.GenerateAllFiles() 29 | data, err = proto.Marshal(g.Response) 30 | if err != nil { 31 | g.Error(err, "failed to marshal output proto") 32 | } 33 | _, err = os.Stdout.Write(data) 34 | if err != nil { 35 | g.Error(err, "failed to write output proto") 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /grpc/server_side_streaming_rpc/howie_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "golang.org/x/net/context" 5 | "google.golang.org/grpc" 6 | "io" 7 | pr "learning_tools/grpc/server_side_streaming_rpc/proto" 8 | "log" 9 | "testing" 10 | ) 11 | 12 | func Test(t *testing.T) { 13 | conn, err := grpc.Dial("127.0.0.1:8080", grpc.WithInsecure()) 14 | if err != nil { 15 | log.Panic(err) 16 | } 17 | client := pr.NewHowieServerClient(conn) 18 | server, err := client.Howie(context.Background(), &pr.Request{Input: "go"}) 19 | if err != nil { 20 | log.Panic(err) 21 | } 22 | for { 23 | data, err := server.Recv() 24 | if err == io.EOF { 25 | log.Println("服务端停止发送") 26 | break 27 | } 28 | if err != nil { 29 | log.Print(err.Error()) 30 | } 31 | log.Println(data.Output) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /grpc/server_side_streaming_rpc/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "google.golang.org/grpc" 5 | pr "learning_tools/grpc/server_side_streaming_rpc/proto" 6 | "log" 7 | "net" 8 | "time" 9 | ) 10 | 11 | type Server struct{} 12 | 13 | func (s *Server) Howie(q *pr.Request, stream pr.HowieServer_HowieServer) error { 14 | var i = 1 15 | for { 16 | i++ 17 | time.Sleep(time.Second) 18 | if err := stream.Send(&pr.Response{Output: time.Now().Format("2006-01-02 15:04:05") + ":" + q.Input}); err != nil { 19 | return err 20 | } 21 | if i == 10 { 22 | return nil 23 | } 24 | } 25 | } 26 | 27 | func main() { 28 | listen, err := net.Listen("tcp", ":8080") 29 | if err != nil { 30 | log.Panic(err) 31 | } 32 | g := grpc.NewServer() 33 | pr.RegisterHowieServerServer(g, &Server{}) 34 | g.Serve(listen) 35 | } 36 | -------------------------------------------------------------------------------- /grpc/server_side_streaming_rpc/proto/howie.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package proto; 3 | 4 | message Request { 5 | string input = 1; 6 | } 7 | 8 | message Response { 9 | string output = 1; 10 | } 11 | 12 | service HowieServer{ 13 | rpc Howie (Request) returns (stream Response){} 14 | } -------------------------------------------------------------------------------- /grpc/simple_rpc/howie_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "golang.org/x/net/context" 5 | "google.golang.org/grpc" 6 | "learning_tools/grpc/etcd-grpc/proto" 7 | "testing" 8 | ) 9 | 10 | func Test(t *testing.T) { 11 | 12 | } 13 | 14 | //BenchmarkA-16 4872 279341 ns/op 15 | func BenchmarkA(b *testing.B) { 16 | for i := 0; i < b.N; i++ { 17 | conn, err := grpc.Dial("127.0.0.1:8099", grpc.WithInsecure()) 18 | if err != nil { 19 | b.Error(err) 20 | } 21 | c := proto.NewHowieClient(conn) 22 | _, err = c.LoL(context.Background(), &proto.HowieUp{Name: "howie"}) 23 | if err != nil { 24 | b.Error(err) 25 | } 26 | 27 | } 28 | } 29 | 30 | //BenchmarkB-16 21667 56072 ns/op 31 | func BenchmarkB(b *testing.B) { 32 | conn, err := grpc.Dial("127.0.0.1:8099", grpc.WithInsecure()) 33 | if err != nil { 34 | b.Error(err) 35 | } 36 | for i := 0; i < b.N; i++ { 37 | c := proto.NewHowieClient(conn) 38 | _, err = c.LoL(context.Background(), &proto.HowieUp{Name: "howie"}) 39 | if err != nil { 40 | b.Error(err) 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /grpc/simple_rpc/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "golang.org/x/net/context" 6 | "google.golang.org/grpc" 7 | pr "learning_tools/grpc/etcd-grpc/proto" 8 | "log" 9 | "net" 10 | ) 11 | 12 | type Server struct{} 13 | 14 | func (s *Server) LoL(ctx context.Context, up *pr.HowieUp) (do *pr.HowieDown, err error) { 15 | do = &pr.HowieDown{Msg: up.Name + "1111"} 16 | return do, nil 17 | 18 | } 19 | 20 | func main() { 21 | listener, err := net.Listen("tcp", ":8099") 22 | if err != nil { 23 | log.Panic(err) 24 | } 25 | g := grpc.NewServer() 26 | pr.RegisterHowieServer(g, &Server{}) 27 | fmt.Println("GRPC 启动成功") 28 | g.Serve(listener) 29 | 30 | } 31 | -------------------------------------------------------------------------------- /hbase/README.md: -------------------------------------------------------------------------------- 1 | docker run -d -h docker-hbase \ 2 | -p 2181:2181 \ 3 | -p 8080:8080 \ 4 | -p 8085:8085 \ 5 | -p 9090:9090 \ 6 | -p 9000:9000 \ 7 | -p 9095:9095 \ 8 | -p 16000:16000 \ 9 | -p 16010:16010 \ 10 | -p 16201:16201 \ 11 | -p 16301:16301 \ 12 | -p 16020:16020\ 13 | --name hbase \ 14 | harisekhon/hbase 15 | 16 | docker exec -it hbase /bin/bash 17 | 18 | hbase shell 19 | 20 | #### info为列簇,不建议有过多列簇 21 | create 'user','info' 22 | 23 | 给 hosts 添加 24 | docker-hbase 你的docker地址 25 | 26 | -------------------------------------------------------------------------------- /hconf/README.md: -------------------------------------------------------------------------------- 1 | ### 基于etcd与viper的高可用配置中心 2 | 3 | - 可使用远程与本地模式 4 | - 本地有的配置远程没有会自动把本地配置传到远程(基于key) 5 | - 远程有的配置本地没有也会写一份到本地(退出程序会把远程配置写一份到本地) 6 | - 远程模式配置可以动态加载 7 | - 如远程连接不上会使用本地配置启动作为兜底 8 | 9 | ```base 10 | var conf = Conf{} 11 | r, err := NewHConf( 12 | SetWatchRootName([]string{"/gs/conf"}), 13 | ) 14 | if err != nil { 15 | t.Error(err) 16 | return 17 | } 18 | t.Log(r.ConfByKey("/gs/conf/net", &conf.Net)) 19 | t.Log(r.ConfByKey("/gs/conf/net2222", &conf.Net2)) 20 | t.Log(r.ConfByKey("/gs/conf/net3333", &conf.Net3)) 21 | if err := r.Run(); err != nil { 22 | t.Error(err) 23 | return 24 | } 25 | t.Log(conf) 26 | t.Log(r.Close()) 27 | ``` 28 | -------------------------------------------------------------------------------- /hconf/hconf.yaml: -------------------------------------------------------------------------------- 1 | /gs/conf/net: 2 | host: "123123111111" 3 | port: "123123" 4 | /gs/conf/net2222: 5 | host: "123123111111" 6 | port: "123123" 7 | -------------------------------------------------------------------------------- /hconf/hconf_test.go: -------------------------------------------------------------------------------- 1 | package hconf 2 | 3 | import ( 4 | clientv3 "go.etcd.io/etcd/client/v3" 5 | "testing" 6 | ) 7 | 8 | type Conf struct { 9 | Net Net 10 | Net2 Net 11 | Net3 Net 12 | } 13 | 14 | type Net struct { 15 | Host string `yaml:"host"` 16 | Port string `yaml:"port"` 17 | } 18 | 19 | func TestHConf(t *testing.T) { 20 | var conf = Conf{} 21 | r, err := NewHConf( 22 | SetWatchRootName([]string{"/gs/conf"}), 23 | SetEtcdConf(clientv3.Config{ 24 | Endpoints: []string{"127.0.0.1:2379"}, 25 | }), 26 | ) 27 | if err != nil { 28 | t.Error(err) 29 | return 30 | } 31 | t.Log(r.ConfByKey("/gs/conf/net", &conf.Net)) 32 | t.Log(r.ConfByKey("/gs/conf/net2222", &conf.Net2)) 33 | t.Log(r.ConfByKey("/gs/conf/net3333", &conf.Net3)) 34 | if err := r.Run(); err != nil { 35 | t.Error(err) 36 | return 37 | } 38 | t.Log(conf) 39 | t.Log(r.Close()) 40 | } 41 | -------------------------------------------------------------------------------- /hconfig/apollo/config_test.go: -------------------------------------------------------------------------------- 1 | package apollo 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestNewEtcdConfig(t *testing.T) { 8 | c, err := NewApolloConfig( 9 | WithAppid("test"), 10 | WithNamespace("test.yaml"), 11 | WithAddr("http://127.0.0.1:32001"), 12 | WithCluster("dev"), 13 | ) 14 | if err != nil { 15 | t.Error(err) 16 | return 17 | } 18 | loadData, err := c.Load() 19 | if err != nil { 20 | t.Error(err) 21 | return 22 | } 23 | for _, v := range loadData { 24 | t.Logf("Load key %s val %s \n", v.Key, string(v.Val)) 25 | } 26 | w, err := c.Watch() 27 | defer w.Close() 28 | if err != nil { 29 | t.Error(err) 30 | return 31 | } 32 | go func() { 33 | for { 34 | kvs, err := w.Change() 35 | if err != nil { 36 | return 37 | } 38 | for _, v := range kvs { 39 | t.Logf("Change key %s val %s \n", v.Key, string(v.Val)) 40 | } 41 | } 42 | }() 43 | select {} 44 | } 45 | -------------------------------------------------------------------------------- /hconfig/etcd/config_test.go: -------------------------------------------------------------------------------- 1 | package etcd 2 | 3 | import ( 4 | "testing" 5 | ) 6 | import clientv3 "go.etcd.io/etcd/client/v3" 7 | 8 | func TestNewEtcdConfig(t *testing.T) { 9 | cli, err := clientv3.New(clientv3.Config{ 10 | Endpoints: []string{"127.0.0.1:2379"}, 11 | }) 12 | if err != nil { 13 | t.Error(err) 14 | return 15 | } 16 | c, err := NewEtcdConfig(cli, WithRoot("/hconf"), WithPaths("app", "mysql")) 17 | if err != nil { 18 | t.Error(err) 19 | return 20 | } 21 | loadData, err := c.Load() 22 | if err != nil { 23 | t.Error(err) 24 | return 25 | } 26 | for _, v := range loadData { 27 | t.Logf("Load key %s val %s \n", v.Key, string(v.Val)) 28 | } 29 | w, err := c.Watch() 30 | defer w.Close() 31 | if err != nil { 32 | t.Error(err) 33 | return 34 | } 35 | go func() { 36 | for { 37 | kvs, err := w.Change() 38 | if err != nil { 39 | return 40 | } 41 | for _, v := range kvs { 42 | t.Logf("Change key %s val %s \n", v.Key, string(v.Val)) 43 | } 44 | } 45 | }() 46 | select {} 47 | } 48 | -------------------------------------------------------------------------------- /hconfig/etcd/options.go: -------------------------------------------------------------------------------- 1 | package etcd 2 | 3 | import ( 4 | "golang.org/x/net/context" 5 | ) 6 | 7 | type Option func(*options) 8 | 9 | // /honf/test 10 | // /honf/test2 11 | // /honf/test3 12 | // /honf/test3/conf/2 13 | type options struct { 14 | ctx context.Context 15 | root string 16 | paths []string 17 | } 18 | 19 | func WithContext(ctx context.Context) Option { 20 | return func(o *options) { 21 | o.ctx = ctx 22 | } 23 | } 24 | 25 | func WithRoot(prefix string) Option { 26 | return func(o *options) { 27 | o.root = prefix 28 | } 29 | } 30 | 31 | func WithPaths(path ...string) Option { 32 | return func(o *options) { 33 | o.paths = path 34 | } 35 | } 36 | 37 | func NewOptions(opts ...Option) *options { 38 | options := &options{ 39 | ctx: context.Background(), 40 | root: "/hconf", 41 | paths: []string{"test"}, 42 | } 43 | for _, opt := range opts { 44 | opt(options) 45 | } 46 | return options 47 | } 48 | -------------------------------------------------------------------------------- /hconfig/h_val.go: -------------------------------------------------------------------------------- 1 | package hconfig 2 | 3 | import ( 4 | "encoding/json" 5 | "gopkg.in/yaml.v2" 6 | ) 7 | 8 | type HVal []byte 9 | 10 | func (h HVal) FormatJson(v interface{}) error { 11 | return json.Unmarshal(h, v) 12 | } 13 | 14 | func (h HVal) FormatYaml(v interface{}) error { 15 | return yaml.Unmarshal(h, v) 16 | } 17 | 18 | func (h HVal) String() string { 19 | return string(h) 20 | } 21 | 22 | func (h HVal) Bytes() []byte { 23 | return h 24 | } 25 | -------------------------------------------------------------------------------- /hconfig/hconf/hconfig.go: -------------------------------------------------------------------------------- 1 | package hconf 2 | 3 | type Data struct { 4 | Key string 5 | Val []byte 6 | } 7 | 8 | type DataSource interface { 9 | Load() ([]*Data, error) 10 | Watch() (DataWatcher, error) 11 | } 12 | 13 | type DataWatcher interface { 14 | Change() ([]*Data, error) 15 | Close() error 16 | } 17 | -------------------------------------------------------------------------------- /hconfig/kubernetes/config_test.go: -------------------------------------------------------------------------------- 1 | package kubernetes 2 | 3 | import "testing" 4 | 5 | func TestNewKubernetesConfig(t *testing.T) { 6 | cli, err := NewK8sClientset(KubeConfigPath("/home/app/conf/kube_config/local_kube.yaml")) 7 | if err != nil { 8 | t.Error(err) 9 | return 10 | } 11 | c, err := NewKubernetesConfig(cli, WithNamespace("im"), WithPaths("im-test-conf", "im-test-conf2")) 12 | if err != nil { 13 | t.Error(err) 14 | return 15 | } 16 | loadData, err := c.Load() 17 | if err != nil { 18 | t.Error(err) 19 | return 20 | } 21 | for _, v := range loadData { 22 | t.Logf("Load key %s val %s \n", v.Key, string(v.Val)) 23 | } 24 | w, err := c.Watch() 25 | defer w.Close() 26 | if err != nil { 27 | t.Error(err) 28 | return 29 | } 30 | go func() { 31 | for { 32 | kvs, err := w.Change() 33 | if err != nil { 34 | return 35 | } 36 | for _, v := range kvs { 37 | t.Logf("Change key %s val %s \n", v.Key, string(v.Val)) 38 | } 39 | } 40 | }() 41 | select {} 42 | } 43 | -------------------------------------------------------------------------------- /hconfig/options.go: -------------------------------------------------------------------------------- 1 | package hconfig 2 | 3 | import ( 4 | "errors" 5 | "github.com/hwholiday/learning_tools/hconfig/hconf" 6 | ) 7 | 8 | type Option func(opt *options) 9 | 10 | type options struct { 11 | dataSource hconf.DataSource 12 | useLocal bool 13 | } 14 | 15 | func WithDataSource(d hconf.DataSource) Option { 16 | return func(opt *options) { 17 | opt.dataSource = d 18 | } 19 | } 20 | 21 | func UseLocal() Option { 22 | return func(opt *options) { 23 | opt.useLocal = true 24 | } 25 | } 26 | 27 | func newOptions(opts ...Option) (*options, error) { 28 | o := &options{ 29 | dataSource: nil, 30 | useLocal: false, 31 | } 32 | for _, opt := range opts { 33 | opt(o) 34 | } 35 | if o.dataSource == nil { 36 | return nil, errors.New("dataSource is nil") 37 | } 38 | return o, nil 39 | } 40 | -------------------------------------------------------------------------------- /hevent/event_test.go: -------------------------------------------------------------------------------- 1 | package hevent 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | "time" 7 | ) 8 | 9 | func TestName(t *testing.T) { 10 | var ch = make(chan HEvent) 11 | var ch2 = make(chan HEvent) 12 | HEventSrv().Sub("hw", ch) 13 | HEventSrv().Sub("hw", ch2) 14 | //go GetHEventSrv().Push("topic1", "Hi topic 1") 15 | go func() { 16 | for { 17 | time.Sleep(1 * time.Second) 18 | HEventSrv().Push("hw", "Hi topic 1") 19 | } 20 | }() 21 | for { 22 | select { 23 | case c := <-ch: 24 | fmt.Println("ch", c) 25 | case c := <-ch2: 26 | fmt.Println("ch2", c) 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /hlb-grpc/example/api.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package proto; 3 | option go_package = "/api"; 4 | 5 | message Request { 6 | string input = 1; 7 | } 8 | 9 | message Response { 10 | string output = 1; 11 | } 12 | //protoc -I. --go_out=plugins=grpc:. api.proto 13 | service Api{ 14 | rpc ApiTest (Request) returns (Response){} 15 | } -------------------------------------------------------------------------------- /hlb-grpc/register/register_test.go: -------------------------------------------------------------------------------- 1 | package register 2 | 3 | import ( 4 | "fmt" 5 | clientv3 "go.etcd.io/etcd/client/v3" 6 | "os" 7 | "os/signal" 8 | "syscall" 9 | "testing" 10 | "time" 11 | ) 12 | 13 | func TestNewServiceRegister(t *testing.T) { 14 | s, err := NewRegister( 15 | SetName("hwholiday.srv.msg"), 16 | SetAddress("127.0.0.1:123123"), 17 | SetVersion("v1"), 18 | SetEtcdConf(clientv3.Config{ 19 | Endpoints: []string{"172.12.12.165:2379"}, 20 | DialTimeout: time.Second * 5, 21 | }), 22 | ) 23 | if err != nil { 24 | panic(err) 25 | } 26 | c := make(chan os.Signal, 1) 27 | go func() { 28 | if s.ListenKeepAliveChan() { 29 | c <- syscall.SIGQUIT 30 | } 31 | }() 32 | signal.Notify(c, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT) 33 | for a := range c { 34 | switch a { 35 | case syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT: 36 | fmt.Println("退出") 37 | _ = s.Close() 38 | return 39 | default: 40 | return 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /hlog/zap_test.go: -------------------------------------------------------------------------------- 1 | package hlog 2 | 3 | import ( 4 | "context" 5 | "github.com/google/uuid" 6 | "go.uber.org/zap" 7 | "testing" 8 | ) 9 | 10 | func TestGetLogger(t *testing.T) { 11 | NewLogger() 12 | GetLogger().Info("hconf example success") 13 | // 可以在中间件内赋值 14 | ctx, hlog := GetLogger().AddCtx(context.Background(), zap.String("traceId", uuid.New().String())) 15 | hlog.Debug("TestGetLogger", zap.Any("t", "t")) 16 | FA(ctx) 17 | FB(ctx) 18 | 19 | // 可以在中间件内赋值 20 | ctx, hlog = GetLogger().AddCtx(context.Background(), zap.String("traceId", uuid.New().String())) 21 | hlog.Info("TestGetLogger", zap.Any("t", "t")) 22 | FA(ctx) 23 | FB(ctx) 24 | } 25 | 26 | func FA(ctx context.Context) { 27 | hlog := GetLogger().GetCtx(ctx) 28 | hlog.Info("FA", zap.Any("a", "a")) 29 | } 30 | 31 | func FB(ctx context.Context) { 32 | hlog := GetLogger().GetCtx(ctx) 33 | hlog.Info("FB", zap.Any("b", "b")) 34 | FC(ctx) 35 | } 36 | func FC(ctx context.Context) { 37 | hlog := GetLogger().GetCtx(ctx) 38 | hlog.Info("FC", zap.Any("c", "c")) 39 | } 40 | -------------------------------------------------------------------------------- /ini/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/go-ini/ini" 6 | ) 7 | 8 | type My struct { 9 | AppModel string `ini:"app_model"` 10 | Type int `ini:"type"` 11 | Sql Mysql `ini:"mysql"` 12 | } 13 | type Mysql struct { 14 | Name string `ini:"name"` 15 | Pass string `ini:"pass"` 16 | } 17 | 18 | func main() { 19 | cfg, err := ini.Load("./ini/my.ini") 20 | if err != nil { 21 | fmt.Println(err) 22 | return 23 | } 24 | fmt.Println(cfg.Section("").Key("app_model").Value()) 25 | fmt.Println(cfg.Section("mysql").Key("name").Value()) 26 | fmt.Println(cfg.Section("mysql").Key("pass").Value()) 27 | p := new(My) 28 | err = cfg.MapTo(p) 29 | if err != nil { 30 | fmt.Println(err) 31 | return 32 | } 33 | fmt.Println(p) 34 | } 35 | -------------------------------------------------------------------------------- /ini/my.ini: -------------------------------------------------------------------------------- 1 | #启动模式 2 | app_model = debug 3 | type = 1 4 | [mysql] 5 | name = root 6 | pass = aa123123123 -------------------------------------------------------------------------------- /interface/f_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | "testing" 7 | ) 8 | 9 | type Srv interface { 10 | Add(a int, b int) (int, error) 11 | Del(a int) error 12 | } 13 | 14 | type srv struct { 15 | } 16 | 17 | func (s *srv) Add(a int, b int) (int, error) { 18 | return a + b, nil 19 | } 20 | func (s *srv) Del(a int) error { 21 | return nil 22 | } 23 | 24 | func Test_interface(t *testing.T) { 25 | var handler Srv 26 | handler = &srv{} 27 | typ := reflect.TypeOf(handler) 28 | hdlr := reflect.ValueOf(handler) 29 | name := reflect.Indirect(hdlr).Type().Name() 30 | fmt.Println(name) 31 | for m := 0; m < typ.NumMethod(); m++ { 32 | fmt.Println("m", m, typ.Method(m).Type) 33 | fmt.Println("m", m, typ.Method(m).Name) 34 | fmt.Println("m", m, typ.Method(m).Func) 35 | fmt.Println("m", m, typ.Method(m).Index) 36 | fmt.Println("m", m, typ.Method(m).PkgPath) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /interface/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "learning_tools/interface/src" 6 | ) 7 | 8 | type AA struct { 9 | a src.Agent 10 | } 11 | 12 | func (a *AA) TestAA() { 13 | fmt.Println("测试AA") 14 | } 15 | func main() { 16 | var A = &AA{} 17 | A.a = src.NewHowie() 18 | A.TestAA() 19 | A.a.Name() 20 | A.a.Run() 21 | } 22 | -------------------------------------------------------------------------------- /interface/middleware/middleware_server.go: -------------------------------------------------------------------------------- 1 | package middleware 2 | 3 | type Service interface { 4 | Add(a, b int) int 5 | } 6 | 7 | type baseServer struct{} 8 | 9 | func NewBaseServer() Service { 10 | return baseServer{} 11 | } 12 | 13 | func (s baseServer) Add(a, b int) int { 14 | return a + b 15 | } 16 | 17 | func NewService(s string) Service { 18 | var svc Service 19 | { 20 | svc = NewBaseServer() 21 | svc = LogMiddleware(s)(svc) 22 | svc = LogV2Middleware(s)(svc) 23 | } 24 | return svc 25 | } 26 | -------------------------------------------------------------------------------- /interface/middleware/middleware_test.go: -------------------------------------------------------------------------------- 1 | package middleware 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func Test_middleware(t *testing.T) { 8 | t.Log("开始运行") 9 | svc := NewService("") 10 | t.Log("结果", svc.Add(1, 2)) 11 | } 12 | -------------------------------------------------------------------------------- /interface/src/Agent.go: -------------------------------------------------------------------------------- 1 | package src 2 | 3 | type Agent interface { 4 | Name() string 5 | Run() 6 | } 7 | -------------------------------------------------------------------------------- /interface/src/Howie.go: -------------------------------------------------------------------------------- 1 | package src 2 | 3 | import "fmt" 4 | 5 | type Howie struct { 6 | Addr string 7 | Data string 8 | } 9 | 10 | func NewHowie() *Howie { 11 | var d = new(Howie) 12 | d.Addr = "127.0.0.1" 13 | d.Data = "我是测试信息i" 14 | return d 15 | } 16 | 17 | func (h *Howie) Name() string { 18 | fmt.Println("调用Name") 19 | return h.Data 20 | } 21 | 22 | func (h *Howie) Run() { 23 | fmt.Println("调用RUN") 24 | } 25 | -------------------------------------------------------------------------------- /istio/api/api.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package api; 3 | 4 | message Req{ 5 | string name = 1; 6 | } 7 | 8 | message Res{ 9 | string name = 2; 10 | } 11 | 12 | service Name{ 13 | rpc ReqName(Req)returns(Res); 14 | rpc ReqVersion(Req)returns(Res); 15 | } -------------------------------------------------------------------------------- /istio/api/cmd.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | protoc --go_out=plugins=grpc:. *.proto -------------------------------------------------------------------------------- /istio/gateway/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM scratch 2 | ADD app /var/app 3 | WORKDIR /var 4 | ENTRYPOINT ["/var/app"] -------------------------------------------------------------------------------- /istio/gateway/README.md: -------------------------------------------------------------------------------- 1 | //gateway 为了简单我们使用以下协议 2 | ```base 3 | { 4 | "code": 1,//协议号 5 | "data": "请求内容", 6 | } 7 | ``` 8 | #### code = 1 请求 logic version 9 | ```base 10 | {"code": 1,"data": ""} 11 | ``` 12 | #### code = 2 请求 ReqName 13 | ```base 14 | {"code": 2,"data": "istio"} 15 | ``` 16 | #### code = 3 请求 测试ws服务 17 | ```base 18 | {"code": 3,"data": "istio"} 19 | ``` 20 | #### 本地测试 ws://127.0.0.1:8888/connect 21 | #### istio测试 ws://172.13.3.131:80/connect (172.13.3.131为你的EXTERNAL-IP) 22 | #### [在线测试WS地址](http://www.easyswoole.com/wstool.html) 23 | #### 安装redis helm install redis-release --set global.storageClass=hw-nfs-storage --set slave.persistence.storageClass=hw-nfs-storge --set master.persistence.storageClass=hw-nfs-storage bitnami/redis -n db-tool 24 | -------------------------------------------------------------------------------- /istio/gateway/build.sh: -------------------------------------------------------------------------------- 1 | CGO_ENABLED=0 GOOS=linux go build -a -ldflags '-extldflags "-static"' -o app . 2 | sudo docker image build -t hwholiday/gateway:v3.0.4 . 3 | sudo docker push hwholiday/gateway:v3.0.4 -------------------------------------------------------------------------------- /istio/kube/net-gateway.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: Gateway 3 | metadata: 4 | name: gateway 5 | namespace: im 6 | spec: 7 | selector: 8 | istio: ingressgateway 9 | servers: 10 | - port: 11 | number: 80 12 | name: http 13 | protocol: HTTP 14 | hosts: 15 | - "*" 16 | --- 17 | apiVersion: networking.istio.io/v1alpha3 18 | kind: VirtualService 19 | metadata: 20 | name: gateway 21 | namespace: im 22 | spec: 23 | hosts: 24 | - "*" 25 | gateways: 26 | - im/gateway 27 | http: 28 | - match: 29 | - uri: 30 | prefix: / 31 | route: 32 | - destination: 33 | host: gateway.im.svc.cluster.local 34 | port: 35 | number: 8888 -------------------------------------------------------------------------------- /istio/kube/net-logic.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: logic 5 | spec: 6 | hosts: 7 | - gateway.im.srv.cluster.local 8 | http: 9 | - route: 10 | - destination: 11 | host: logic.im.svc.cluster.local 12 | --- 13 | apiVersion: networking.istio.io/v1alpha3 14 | kind: DestinationRule 15 | metadata: 16 | name: logic 17 | spec: 18 | host: logic.im.srv.cluster.local 19 | trafficPolicy: 20 | loadBalancer: 21 | simple: RANDOM -------------------------------------------------------------------------------- /istio/kube/net-redis.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: redis-master-1 5 | spec: 6 | ports: 7 | - port: 7001 8 | --- 9 | kind: Endpoints 10 | apiVersion: v1 11 | metadata: 12 | name: redis-master-1 13 | subsets: 14 | - addresses: 15 | - ip: 172.13.3.160 16 | ports: 17 | - port: 7001 18 | --- 19 | apiVersion: v1 20 | kind: Service 21 | metadata: 22 | name: redis-master-2 23 | spec: 24 | ports: 25 | - port: 7002 26 | --- 27 | kind: Endpoints 28 | apiVersion: v1 29 | metadata: 30 | name: redis-master-2 31 | subsets: 32 | - addresses: 33 | - ip: 172.13.3.160 34 | ports: 35 | - port: 7002 36 | --- 37 | apiVersion: v1 38 | kind: Service 39 | metadata: 40 | name: redis-master-3 41 | spec: 42 | ports: 43 | - port: 7003 44 | --- 45 | kind: Endpoints 46 | apiVersion: v1 47 | metadata: 48 | name: redis-master-3 49 | subsets: 50 | - addresses: 51 | - ip: 172.13.3.160 52 | ports: 53 | - port: 7003 -------------------------------------------------------------------------------- /istio/kube/nfs-pvc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: im-nfs 5 | namespace: im 6 | labels: 7 | app: im-nfs 8 | spec: 9 | accessModes: [ "ReadWriteOnce" ] 10 | storageClassName: hw-nfs-storage 11 | resources: 12 | requests: 13 | storage: "10Gi" -------------------------------------------------------------------------------- /istio/kube/nfs-sc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: storage.k8s.io/v1 2 | kind: StorageClass 3 | metadata: 4 | name: hw-nfs-storage 5 | annotations: 6 | storageclass.kubernetes.io/is-default-class: "true" 7 | provisioner: g.hw.com/nfs # or choose another name, must match deployment's env PROVISIONER_NAME' 8 | reclaimPolicy: Retain 9 | parameters: 10 | archiveOnDelete: "false" -------------------------------------------------------------------------------- /istio/kube/nfs-test.yaml: -------------------------------------------------------------------------------- 1 | kind: Pod 2 | apiVersion: v1 3 | metadata: 4 | name: nfs-test 5 | namespace: im 6 | spec: 7 | containers: 8 | - name: nfs-test 9 | image: busybox:1.24 10 | command: 11 | - "/bin/sh" 12 | args: 13 | - "-c" 14 | - "touch /mnt/SUCCESS && exit 0 || exit 1" #创建一个SUCCESS文件后退出 15 | volumeMounts: 16 | - name: nfs-pvc 17 | mountPath: "/mnt" 18 | restartPolicy: "Never" 19 | volumes: 20 | - name: nfs-pvc 21 | persistentVolumeClaim: 22 | claimName: im-nfs #与PVC名称保持一致 -------------------------------------------------------------------------------- /istio/logic_v1/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM scratch 2 | ADD app /var/app 3 | WORKDIR /var 4 | ENTRYPOINT ["/var/app"] -------------------------------------------------------------------------------- /istio/logic_v1/build.sh: -------------------------------------------------------------------------------- 1 | CGO_ENABLED=0 GOOS=linux go build -a -ldflags '-extldflags "-static"' -o app . 2 | sudo docker image build -t hwholiday/logic:v1 . 3 | sudo docker push hwholiday/logic:v1 -------------------------------------------------------------------------------- /istio/logic_v1/logicV1.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "github.com/hwholiday/learning_tools/istio/api" 7 | "google.golang.org/grpc" 8 | "log" 9 | "net" 10 | ) 11 | 12 | const version = "logic_v1" 13 | 14 | type Server struct{} 15 | 16 | func (s *Server) ReqName(c context.Context, req *api.Req) (*api.Res, error) { 17 | fmt.Println(version, " ReqName ", req.Name) 18 | return &api.Res{Name: fmt.Sprintf("%s_%s", version, req.Name)}, nil 19 | } 20 | 21 | func (s *Server) ReqVersion(c context.Context, req *api.Req) (*api.Res, error) { 22 | return &api.Res{Name: version}, nil 23 | } 24 | 25 | func main() { 26 | listener, err := net.Listen("tcp", ":8099") 27 | if err != nil { 28 | log.Panic(err) 29 | } 30 | g := grpc.NewServer() 31 | api.RegisterNameServer(g, &Server{}) 32 | fmt.Println("GRPC 8099 启动成功") 33 | err = g.Serve(listener) 34 | if err != nil { 35 | panic(err) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /istio/logic_v2/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM scratch 2 | ADD app /var/app 3 | WORKDIR /var 4 | ENTRYPOINT ["/var/app"] -------------------------------------------------------------------------------- /istio/logic_v2/build.sh: -------------------------------------------------------------------------------- 1 | CGO_ENABLED=0 GOOS=linux go build -a -ldflags '-extldflags "-static"' -o app . 2 | sudo docker image build -t hwholiday/logic:v2 . 3 | sudo docker push hwholiday/logic:v2 -------------------------------------------------------------------------------- /istio/logic_v2/logicV2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "github.com/hwholiday/learning_tools/istio/api" 7 | "google.golang.org/grpc" 8 | "log" 9 | "net" 10 | ) 11 | 12 | const version = "logic_v2" 13 | 14 | type Server struct{} 15 | 16 | func (s *Server) ReqName(c context.Context, req *api.Req) (*api.Res, error) { 17 | fmt.Println(version, " ReqName ", req.Name) 18 | return &api.Res{Name: fmt.Sprintf("%s_%s", version, req.Name)}, nil 19 | } 20 | 21 | func (s *Server) ReqVersion(c context.Context, req *api.Req) (*api.Res, error) { 22 | return &api.Res{Name: version}, nil 23 | } 24 | 25 | func main() { 26 | listener, err := net.Listen("tcp", ":8099") 27 | if err != nil { 28 | log.Panic(err) 29 | } 30 | g := grpc.NewServer() 31 | api.RegisterNameServer(g, &Server{}) 32 | fmt.Println("GRPC 8099 启动成功") 33 | err = g.Serve(listener) 34 | if err != nil { 35 | panic(err) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /istio/logic_v3/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM scratch 2 | ADD app /var/app 3 | WORKDIR /var 4 | ENTRYPOINT ["/var/app"] -------------------------------------------------------------------------------- /istio/logic_v3/build.sh: -------------------------------------------------------------------------------- 1 | CGO_ENABLED=0 GOOS=linux go build -a -ldflags '-extldflags "-static"' -o app . 2 | sudo docker image build -t hwholiday/logic:v3.04 . 3 | sudo docker push hwholiday/logic:v3.04 -------------------------------------------------------------------------------- /job_worker_mode/debug_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | "time" 7 | ) 8 | 9 | func Test(t *testing.T) { 10 | dis := NewDisPatcher(2, 4) 11 | dis.Run() 12 | for { 13 | time.Sleep(time.Second * 3) 14 | dis.JobQueue <- Goods{Data: []byte(fmt.Sprint(time.Now().UnixNano()))} 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /job_worker_mode/dispatcher.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type DisPatcher struct { 4 | Worker chan chan Goods 5 | JobQueue chan Goods 6 | MaxWorker int 7 | } 8 | 9 | func NewDisPatcher(maxWorker, maxQueue int) *DisPatcher { 10 | return &DisPatcher{ 11 | Worker: make(chan chan Goods, maxWorker), MaxWorker: maxWorker, 12 | JobQueue: make(chan Goods, maxQueue), 13 | } 14 | } 15 | 16 | func (d *DisPatcher) Run() { 17 | for i := 0; i < d.MaxWorker; i++ { 18 | worker := NewWorker(d.Worker) 19 | worker.Start() 20 | } 21 | 22 | go d.dispatch() 23 | } 24 | 25 | func (d *DisPatcher) dispatch() { 26 | for { 27 | select { 28 | case goods := <-d.JobQueue: 29 | go func(good Goods) { 30 | jobChannel := <-d.Worker 31 | jobChannel <- goods 32 | }(goods) 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /job_worker_mode/goods.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type Goods struct { 4 | Data []byte 5 | } 6 | 7 | func (g Goods) UpdateServer() { 8 | 9 | } 10 | -------------------------------------------------------------------------------- /job_worker_mode/worker.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type Worker struct { 8 | WorkerPool chan chan Goods 9 | JobChannel chan Goods 10 | Quit chan bool 11 | } 12 | 13 | func NewWorker(pool chan chan Goods) *Worker { 14 | return &Worker{ 15 | WorkerPool: pool, 16 | JobChannel: make(chan Goods), 17 | Quit: make(chan bool), 18 | } 19 | } 20 | func (w *Worker) Start() { 21 | go func() { 22 | for { 23 | //将当前工作者注册到工作队列中 24 | w.WorkerPool <- w.JobChannel 25 | select { 26 | case goods := <-w.JobChannel: 27 | //执行该程序 28 | goods.UpdateServer() 29 | fmt.Println("worker UpdateServer ") 30 | case <-w.Quit: 31 | fmt.Println("worker服务停止") 32 | return 33 | } 34 | } 35 | }() 36 | } 37 | func (w *Worker) Stop() { 38 | go func() { 39 | w.Quit <- true 40 | }() 41 | } 42 | -------------------------------------------------------------------------------- /jwt/conf/rsa_private_key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIICXQIBAAKBgQC/+42QwaCvwNeJ9yZ1y5jYEYpw2CKTUZIn2Jc/UF+bRf0WOLUQ 3 | exz1rQ5wTRRD/9c0KaIZLNVk7/DMzXXZRfMVvIEd73eVSQYYbnuehWX5zztRq5wv 4 | 3ty/lNw2a5aoMJiZWzrxoeGItMSBMjrwK8ub5xyTXWt6Zomjwa4pZSEHTwIDAQAB 5 | AoGAM9gYuLixTgUDr8xAZJsgoWjLPAICBEqI75276msoBmR2HiQeMV8tyOJ8/bKz 6 | AFH8qad8kNPcpK9vFb9+TbhoFkTPl+J3xZ0ftPNETtI2aVflF/U7OzFPPxicgxwh 7 | v6FCGZmmPpUBxmsdKASqf2/uNYhB/A33iSRxI+SOm0t5fpECQQDk3J4MwJe3qkMH 8 | 4sNL3DL6NbukhAh3wE7bKgCammi1Y33Aj18/095pCuG2v6HcMc7UtdLR9w7YtePz 9 | NPpW5felAkEA1r9sVAJLLG6x3GGR94gMHVcN9092K72hpdO3CVtuN6GcdhODaH/j 10 | csHwOmHRNlI8iB+yKtXIKKBk2wWNrxGw4wJBAOGilPxToQEGDyImMo+HIIdJFJ/l 11 | QIf4BIbVSVUjqNo0pdWERM8j7mI3xUMsecMjJBzYymoRnwSPh5bPg4TLI7UCQQC6 12 | dNSTELbCqo5F4nXBrd+O7hJTRCw/iFQ9Tlkjh75oEStvnju/1SLgdiGmH15uwvKJ 13 | 4rNo29wB4loPjX/anQqvAkA5jcnbKup0FooL1YzfXHhQWvgF8lIb/drqWy8QlwGB 14 | ZDW8Q5YDxeIKcxEeX6Lbye1MWnpbMHlTFa04AR2E+jTU 15 | -----END RSA PRIVATE KEY----- 16 | -------------------------------------------------------------------------------- /jwt/conf/rsa_public_key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC/+42QwaCvwNeJ9yZ1y5jYEYpw 3 | 2CKTUZIn2Jc/UF+bRf0WOLUQexz1rQ5wTRRD/9c0KaIZLNVk7/DMzXXZRfMVvIEd 4 | 73eVSQYYbnuehWX5zztRq5wv3ty/lNw2a5aoMJiZWzrxoeGItMSBMjrwK8ub5xyT 5 | XWt6Zomjwa4pZSEHTwIDAQAB 6 | -----END PUBLIC KEY----- 7 | -------------------------------------------------------------------------------- /jwt/controller/base.go: -------------------------------------------------------------------------------- 1 | package controller 2 | 3 | type BaseController struct { 4 | } 5 | 6 | func (c *BaseController) GetJwtKey() string { 7 | return "holiday" 8 | } 9 | -------------------------------------------------------------------------------- /jwt/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "learning_tools/jwt/controller" 5 | "log" 6 | "net/http" 7 | "time" 8 | ) 9 | 10 | func main() { 11 | mux := http.NewServeMux() 12 | token := &controller.TokenController{} 13 | mux.HandleFunc("/create_token", token.CreateToken) 14 | mux.HandleFunc("/create_rsa_token", token.CreateTokenByRsa) 15 | mux.HandleFunc("/test_token", token.TestToken) 16 | mux.HandleFunc("/test_rsa_token", token.TestRsaToken) 17 | s := &http.Server{ 18 | Addr: ":8080", 19 | Handler: mux, 20 | ReadTimeout: 10 * time.Second, 21 | WriteTimeout: 10 * time.Second, 22 | MaxHeaderBytes: 1 << 20, 23 | } 24 | log.Println("服务器启动成功:8080") 25 | err := s.ListenAndServe() 26 | if err != nil { 27 | log.Panic(err) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /k8s-api/pod.yaml: -------------------------------------------------------------------------------- 1 | # kubectl create namespace k8s-test-pod 2 | # kubectl apply -n k8s-test-pod -f pod.yaml 3 | apiVersion: apps/v1 4 | kind: Deployment 5 | metadata: 6 | name: nginx 7 | labels: 8 | app: nginx 9 | spec: 10 | replicas: 1 11 | selector: 12 | matchLabels: 13 | app: nginx 14 | template: 15 | metadata: 16 | labels: 17 | app: nginx 18 | app-name: "test-app" 19 | app-version: "v1.1.1" 20 | annotations: 21 | app-metadata: "test" 22 | spec: 23 | containers: 24 | - name: nginx 25 | image: nginx:1.7.9 26 | ports: 27 | - containerPort: 80 -------------------------------------------------------------------------------- /k8s/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM scratch 2 | ADD app /var/app 3 | WORKDIR /var 4 | ENTRYPOINT ["/var/app"] -------------------------------------------------------------------------------- /k8s/app.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: app-deployment 5 | labels: 6 | app: app 7 | spec: 8 | selector: 9 | matchLabels: 10 | app: app 11 | replicas: 1 12 | template: 13 | metadata: 14 | labels: 15 | app: app 16 | spec: 17 | containers: 18 | - name: app 19 | image: hwholiday/app:v1 20 | ports: 21 | - containerPort: 8080 -------------------------------------------------------------------------------- /k8s/app_service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: app-service 5 | labels: 6 | app: app 7 | spec: 8 | selector: 9 | app: app 10 | ports: 11 | - name: app-port 12 | protocol: TCP 13 | port: 8080 14 | targetPort: 8080 15 | nodePort: 31080 16 | type: NodePort -------------------------------------------------------------------------------- /k8s/ci-cd/.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | variables: 2 | REGISTRY: "harbor.huoys-im.xyz" 3 | REGISTRY_IMAGE: "harbor.huoys-im.xyz/hw/app" 4 | REGISTRY_USER: "admin" 5 | REGISTRY_PASSWORD: "Harbor12345" 6 | before_script: 7 | - export VERSION=`echo ${CI_COMMIT_TAG} | awk -F"_" '{print $1}'` 8 | stages: 9 | - logs 10 | - build 11 | logs: 12 | stage: logs 13 | tags: 14 | - test 15 | script: 16 | - echo "我是 logs 任务" 17 | - echo "CI_COMMIT_TAG" 18 | - echo ${CI_COMMIT_TAG} 19 | - echo "CI_PROJECT_NAME" 20 | - echo ${CI_PROJECT_NAME} 21 | only: 22 | - tags 23 | build: 24 | stage: build 25 | tags: 26 | - test 27 | image: 28 | name: gcr.io/kaniko-project/executor:debug 29 | entrypoint: [ "" ] 30 | script: 31 | - mkdir -p /kaniko/.docker 32 | - echo "{\"auths\":{\"$REGISTRY\":{\"username\":\"$REGISTRY_USER\",\"password\":\"$REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json 33 | - /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile --destination $REGISTRY_IMAGE:$CI_COMMIT_TAG 34 | only: 35 | - tags -------------------------------------------------------------------------------- /k8s/ci-cd/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.15.6 as build 2 | COPY . /build/ 3 | WORKDIR /build 4 | # RUN go mod download 5 | RUN CGO_ENABLED=0 GOOS=linux go build -a -ldflags '-extldflags "-static"' -o app . 6 | 7 | FROM scratch 8 | COPY --from=build /build/app / 9 | ENTRYPOINT ["/app"] -------------------------------------------------------------------------------- /k8s/ci-cd/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "net/http" 4 | 5 | func main() { 6 | http.HandleFunc("/k8s", func(writer http.ResponseWriter, request *http.Request) { 7 | _, _ = writer.Write([]byte("hello world k8s")) 8 | }) 9 | _ = http.ListenAndServe(":8080", nil) 10 | } 11 | -------------------------------------------------------------------------------- /k8s/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "net/http" 4 | 5 | func main() { 6 | http.HandleFunc("/k8s", func(writer http.ResponseWriter, request *http.Request) { 7 | _, _ = writer.Write([]byte("hello world k8s")) 8 | }) 9 | _ = http.ListenAndServe(":8080", nil) 10 | } 11 | -------------------------------------------------------------------------------- /k8s/nginx.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: nginx-deployment 5 | labels: 6 | app: nginx 7 | spec: 8 | selector: 9 | matchLabels: 10 | app: nginx 11 | replicas: 1 12 | template: 13 | metadata: 14 | labels: 15 | app: nginx 16 | spec: 17 | containers: 18 | - name: nginx 19 | image: nginx 20 | ports: 21 | - containerPort: 80 -------------------------------------------------------------------------------- /k8s/nginx_service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: nginx-service 5 | labels: 6 | app: nginx 7 | spec: 8 | selector: 9 | app: nginx 10 | ports: 11 | - name: nginx-port 12 | protocol: TCP 13 | port: 80 14 | targetPort: 80 15 | nodePort: 30080 16 | type: NodePort -------------------------------------------------------------------------------- /makefile/Makefile: -------------------------------------------------------------------------------- 1 | #环境变量 2 | export VERSION=1.0.0 3 | export ENV=prod 4 | export PROJECT=test 5 | #变量 6 | PWD=$(shell pwd) 7 | OUT_DIR=$(PWD)/cmd 8 | OUT_NAME=$(PROJECT)_$(VERSION) 9 | OUT_FILE=$(OUT_DIR)/$(OUT_NAME) 10 | MAIN_FILE=main.go 11 | PACK_FILE=$(OUT_NAME).tar.gz 12 | 13 | build: 14 | @echo "移除老项目" 15 | @ rm -rf $(OUT_DIR)/* 16 | @go build -o $(OUT_FILE) $(MAIN_FILE) 17 | 18 | @echo "构建项目成功 : " $(OUT_NAME) 19 | 20 | run:build 21 | @# 执行pack前先执行一次build 22 | @echo "运行项目" 23 | @$(OUT_FILE) 24 | 25 | pack:build 26 | @# 执行pack前先执行一次build 27 | tar -czvf $(PACK_FILE) -C $(OUT_DIR) . 28 | @echo "打包结束 :" -------------------------------------------------------------------------------- /makefile/README.md: -------------------------------------------------------------------------------- 1 | ## 什么是MakeFile 2 | Makefile文件的作用是告诉make工具需要如何去编译和链接程序,在需要编译工程时只需要一个make命令即可,避免了每次编译都要重新输入完整命令的麻烦,大大提高了效率,也减少了出错率。 3 | ## 目录 4 | ```base 5 | ├── main.go 6 | ├── Makefile 7 | └── README.md 8 | ``` 9 | ## Makefile 例子 10 | ```base 11 | #环境变量 12 | export VERSION=1.0.0 13 | export ENV=prod 14 | export PROJECT=test 15 | #变量 16 | PWD=$(shell pwd) 17 | OUT_DIR=$(PWD)/cmd 18 | OUT_NAME=$(PROJECT)_$(VERSION) 19 | OUT_FILE=$(OUT_DIR)/$(OUT_NAME) 20 | MAIN_FILE=main.go 21 | PACK_FILE=$(OUT_NAME).tar.gz 22 | 23 | build: 24 | @echo "移除老项目" 25 | @ rm -rf $(OUT_DIR)/* 26 | @go build -o $(OUT_FILE) $(MAIN_FILE) 27 | 28 | @echo "构建项目成功 : " $(OUT_NAME) 29 | 30 | run:build 31 | @# 执行pack前先执行一次build 32 | @echo "运行项目" 33 | @$(OUT_FILE) 34 | 35 | pack:build 36 | @# 执行pack前先执行一次build 37 | tar -czvf $(PACK_FILE) -C $(OUT_DIR) . 38 | @echo "打包结束 :" 39 | ``` 40 | ## 构建命令 41 | ```base 42 | # 带上环境变量 43 | make build ENV="prod" VERSION="2.0.0" PROJECT="test_makefile" 44 | ``` 45 | 46 | ## 打包命令 47 | ```base 48 | make pack 49 | ``` 50 | ## 运行命令 51 | ```base 52 | make run 53 | ``` -------------------------------------------------------------------------------- /makefile/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | fmt.Println("hello makefile") 7 | } 8 | -------------------------------------------------------------------------------- /micro_agent/README.md: -------------------------------------------------------------------------------- 1 | # micro 微服务实践,可能是写的好的哪一种 2 | ### [micro_agent](https://github.com/hwholiday/learning_tools/tree/master/micro_agent) (micro微服务) 3 | 1: base 基础方法 4 | 2: conf 配置文件 5 | 3:handler 对外处理方法 6 | 4:model 数据格式 7 | 5:proto protobuf 文件 8 | 9 | -------------------------------------------------------------------------------- /micro_agent/base/base.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | import ( 4 | "micro_agent/base/config" 5 | "micro_agent/base/db" 6 | "micro_agent/base/tool" 7 | ) 8 | 9 | func Init(path string) { 10 | config.Init(path) 11 | db.Init() 12 | tool.Init() 13 | } 14 | -------------------------------------------------------------------------------- /micro_agent/base/config/config.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "path/filepath" 5 | "sync" 6 | ) 7 | import "github.com/go-ini/ini" 8 | 9 | var ( 10 | mysqlConfig defaultMysqlConfig 11 | serConfig defaultServerConfig 12 | utilsConfig defaultLogToolConfig 13 | m sync.Mutex 14 | ) 15 | 16 | func Init(path string) { 17 | var ( 18 | err error 19 | cfg *ini.File 20 | ) 21 | 22 | m.Lock() 23 | defer m.Unlock() 24 | if err = ini.MapTo(&mysqlConfig, filepath.Join(path, "mysql.ini")); err != nil { 25 | panic(err) 26 | } 27 | if err = ini.MapTo(&serConfig, filepath.Join(path, "user_agent.ini")); err != nil { 28 | panic(err) 29 | } 30 | if cfg, err = ini.Load(filepath.Join(path, "tool.ini")); err != nil { 31 | 32 | } 33 | if err = cfg.Section("zap").MapTo(&utilsConfig); err != nil { 34 | panic(err) 35 | } 36 | } 37 | 38 | func GetMysqlConfig() (fig sqlConfig) { 39 | return mysqlConfig 40 | } 41 | func GetServerConfig() (fig serverConfig) { 42 | return serConfig 43 | } 44 | func GetToolLogConfig() (fig toolLogConfig) { 45 | return utilsConfig 46 | } 47 | -------------------------------------------------------------------------------- /micro_agent/base/config/mysql.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | type sqlConfig interface { 4 | GetIp() string 5 | GetPort() string 6 | GetName() string 7 | GetPass() string 8 | GetDb() string 9 | GetMaxIdle() int 10 | GetMaxOpen() int 11 | } 12 | 13 | type defaultMysqlConfig struct { 14 | Ip string `ini:"ip"` 15 | Port string `ini:"port"` 16 | Name string `ini:"name"` 17 | Pass string `ini:"pass"` 18 | Db string `ini:"db"` 19 | MaxIdle int `ini:"max_idle"` 20 | MaxOpen int `ini:"max_open"` 21 | } 22 | 23 | func (m defaultMysqlConfig) GetIp() string { 24 | return m.Ip 25 | } 26 | func (m defaultMysqlConfig) GetPort() string { 27 | return m.Port 28 | } 29 | func (m defaultMysqlConfig) GetName() string { 30 | return m.Name 31 | } 32 | func (m defaultMysqlConfig) GetPass() string { 33 | return m.Pass 34 | } 35 | func (m defaultMysqlConfig) GetDb() string { 36 | return m.Db 37 | } 38 | func (m defaultMysqlConfig) GetMaxIdle() int { 39 | return m.MaxIdle 40 | } 41 | func (m defaultMysqlConfig) GetMaxOpen() int { 42 | return m.MaxOpen 43 | } 44 | -------------------------------------------------------------------------------- /micro_agent/base/config/server.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | type serverConfig interface { 4 | GetAppMode() string 5 | AppIsDebug() bool 6 | GetServerName() string 7 | GetEtcdAddr() string 8 | GetBlack() []string 9 | } 10 | 11 | type defaultServerConfig struct { 12 | AppMode string `ini:"app_mode"` 13 | ServerName string `ini:"server_name"` 14 | EtcdAddr string `ini:"etcd_addr"` 15 | List list `ini:"list"` 16 | } 17 | type list struct { 18 | Black []string `ini:"black"` 19 | } 20 | 21 | func (s defaultServerConfig) GetAppMode() string { 22 | return s.AppMode 23 | } 24 | func (s defaultServerConfig) AppIsDebug() bool { 25 | if s.AppMode == "debug" { 26 | return true 27 | } 28 | return false 29 | } 30 | func (s defaultServerConfig) GetServerName() string { 31 | return s.ServerName 32 | } 33 | func (s defaultServerConfig) GetEtcdAddr() string { 34 | return s.EtcdAddr 35 | } 36 | func (s defaultServerConfig) GetBlack() []string { 37 | return s.List.Black 38 | } 39 | -------------------------------------------------------------------------------- /micro_agent/base/db/db.go: -------------------------------------------------------------------------------- 1 | package db 2 | 3 | import ( 4 | _ "github.com/go-sql-driver/mysql" 5 | "github.com/go-xorm/xorm" 6 | "sync" 7 | ) 8 | 9 | var ( 10 | err error 11 | mysqlDb *xorm.Engine 12 | m sync.Mutex 13 | ) 14 | 15 | func Init() { 16 | m.Lock() 17 | defer m.Unlock() 18 | initMysql() 19 | } 20 | 21 | func GetMySqlDb() *xorm.Engine { 22 | return mysqlDb 23 | } 24 | 25 | func CloseMySqlDb() { 26 | closeMysql() 27 | } 28 | -------------------------------------------------------------------------------- /micro_agent/base/db/mysql.go: -------------------------------------------------------------------------------- 1 | package db 2 | 3 | import ( 4 | "fmt" 5 | "github.com/go-xorm/xorm" 6 | "micro_agent/base/config" 7 | ) 8 | 9 | func initMysql() { 10 | if mysqlDb, err = xorm.NewEngine("mysql", fmt.Sprintf("%s:%s@(%s:%s)/%s?charset=utf8", 11 | config.GetMysqlConfig().GetName(), config.GetMysqlConfig().GetPass(), config.GetMysqlConfig().GetIp(), config.GetMysqlConfig().GetIp(), config.GetMysqlConfig().GetPort())); err != nil { 12 | panic(err) 13 | } 14 | mysqlDb.SetMaxOpenConns(config.GetMysqlConfig().GetMaxIdle()) 15 | mysqlDb.SetMaxIdleConns(config.GetMysqlConfig().GetMaxOpen()) 16 | _ = mysqlDb.Ping() 17 | if config.GetServerConfig().AppIsDebug() { 18 | mysqlDb.ShowSQL(true) 19 | mysqlDb.ShowExecTime(true) 20 | } 21 | //tbMapper := core.NewPrefixMapper(core.SnakeMapper{}, "im_") 22 | //mysqlDb.SetTableMapper(tbMapper) 23 | } 24 | 25 | func closeMysql() { 26 | if mysqlDb != nil { 27 | _ = mysqlDb.Close() 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /micro_agent/base/tool/tool.go: -------------------------------------------------------------------------------- 1 | package tool 2 | 3 | import ( 4 | "micro_agent/base/config" 5 | ) 6 | 7 | func Init() { 8 | initLogger(getLoggerOptions()) 9 | } 10 | func getLoggerOptions() *Options { 11 | op := &Options{} 12 | op.Development = config.GetToolLogConfig().GetDevelopment() 13 | op.LogFileDir = config.GetToolLogConfig().GetLogFileDir() 14 | op.AppName = config.GetToolLogConfig().GetAppName() 15 | op.MaxSize = config.GetToolLogConfig().GetMaxSize() 16 | op.MaxBackups = config.GetToolLogConfig().GetMaxBackups() 17 | op.MaxAge = config.GetToolLogConfig().GetMaxAge() 18 | return op 19 | } 20 | -------------------------------------------------------------------------------- /micro_agent/conf/mysql.ini: -------------------------------------------------------------------------------- 1 | ip = 127.0.0.1 2 | port = 3306 3 | name = root 4 | pass = 123qwe 5 | db = test 6 | max_idle = 10 7 | max_open = 100 -------------------------------------------------------------------------------- /micro_agent/conf/tool.ini: -------------------------------------------------------------------------------- 1 | [zap] 2 | #appName 日志的前缀 3 | appName = micro_agent 4 | #development 是否开发模式 5 | development = true 6 | #logFileDir 日志文件存放目录 7 | logFileDir =logs 8 | #maxSize 日志文件大小最大值 9 | maxSize = 50 10 | #maxBackups 最大保存文件数 11 | maxBackups = 200 12 | #maxAge 最大保存天数 13 | maxAge = 10 -------------------------------------------------------------------------------- /micro_agent/conf/user_agent.ini: -------------------------------------------------------------------------------- 1 | app_mode = debug 2 | server_name = im.srv.user 3 | etcd_addr = 127.0.0.1:7080 4 | [list] 5 | black = 敏感词汇1,敏感词汇2,敏感词汇3 -------------------------------------------------------------------------------- /micro_agent/handler/hander.go: -------------------------------------------------------------------------------- 1 | package handler 2 | 3 | import ( 4 | "micro_agent/model/user" 5 | "sync" 6 | ) 7 | 8 | var ( 9 | err error 10 | server *Service 11 | m sync.Mutex 12 | ) 13 | 14 | type Service struct { 15 | userServer user.Service 16 | } 17 | 18 | func GetService() *Service { 19 | return server 20 | } 21 | 22 | func Init() { 23 | m.Lock() 24 | defer m.Unlock() 25 | server = new(Service) 26 | server.userServer, err = user.GetService() 27 | checkErr(err) 28 | 29 | } 30 | 31 | func checkErr(err error) { 32 | if err != nil { 33 | panic(err) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /micro_agent/handler/user.go: -------------------------------------------------------------------------------- 1 | package handler 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | user_agent "micro_agent/proto/user" 7 | ) 8 | 9 | func (s *Service) RpcUserInfo(ctx context.Context, req *user_agent.ReqMsg, res *user_agent.ResMsg) error { 10 | fmt.Println(s.userServer.UserInfo(req)) 11 | return nil 12 | } 13 | -------------------------------------------------------------------------------- /micro_agent/model/model.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import "micro_agent/model/user" 4 | 5 | func Init() { 6 | user.Init() 7 | } 8 | -------------------------------------------------------------------------------- /micro_agent/model/user/user.go: -------------------------------------------------------------------------------- 1 | package user 2 | 3 | import ( 4 | "fmt" 5 | user_agent "micro_agent/proto/user" 6 | "sync" 7 | ) 8 | 9 | var ( 10 | s *service 11 | m sync.RWMutex 12 | ) 13 | 14 | type service struct{} 15 | 16 | type Service interface { 17 | UserInfo(msg *user_agent.ReqMsg) (info string, err error) 18 | } 19 | 20 | func Init() { 21 | m.Lock() 22 | defer m.Unlock() 23 | if s != nil { 24 | return 25 | } 26 | s = &service{} 27 | } 28 | 29 | func GetService() (Service, error) { 30 | if s == nil { 31 | return nil, fmt.Errorf("[GetService] GetService 未初始化") 32 | } 33 | return s, nil 34 | } 35 | -------------------------------------------------------------------------------- /micro_agent/model/user/user_info.go: -------------------------------------------------------------------------------- 1 | package user 2 | 3 | import user_agent "micro_agent/proto/user" 4 | 5 | func (s *service) UserInfo(msg *user_agent.ReqMsg) (info string, err error) { 6 | 7 | return 8 | } 9 | -------------------------------------------------------------------------------- /micro_agent/proto/user/make.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | protoc --micro_out=. --go_out=. *.proto -------------------------------------------------------------------------------- /micro_agent/proto/user/user.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package user_agent; 3 | service User { 4 | rpc RpcUserInfo (ReqMsg) returns (ResMsg) { 5 | } 6 | } 7 | 8 | message Error { 9 | int32 code = 1; 10 | string msg = 2; 11 | } 12 | 13 | message ReqMsg { 14 | string user_name = 1; 15 | } 16 | 17 | message ResMsg { 18 | Error error = 1; 19 | string info=2; 20 | } -------------------------------------------------------------------------------- /micro_agent/resource/0190627140759.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hwholiday/learning_tools/71e1320fd3e105ddfde80cc0a88e70d7ad7a41cd/micro_agent/resource/0190627140759.png -------------------------------------------------------------------------------- /micro_v2/config/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/micro/go-micro/v2/config" 6 | "github.com/micro/go-micro/v2/config/encoder/toml" 7 | "github.com/micro/go-micro/v2/config/source" 8 | "github.com/micro/go-micro/v2/config/source/etcd" 9 | ) 10 | 11 | func main() { 12 | conf, err := config.NewConfig() 13 | if err != nil { 14 | panic(err) 15 | } 16 | t := toml.NewEncoder() 17 | sou := etcd.NewSource( 18 | etcd.WithAddress("192.168.1.86:2379"), 19 | etcd.WithPrefix("/conf/"), 20 | etcd.StripPrefix(true), 21 | source.WithEncoder(t), 22 | ) 23 | if err = conf.Load(sou); err != nil { 24 | panic(err) 25 | } 26 | fmt.Println("读取到配置", string(conf.Get("test", "server").Bytes())) 27 | wath, err := conf.Watch("test", "server") 28 | if err != nil { 29 | panic(err) 30 | } 31 | defer wath.Stop() 32 | for { 33 | val, err := wath.Next() 34 | if err != nil { 35 | panic(err) 36 | } 37 | fmt.Println(string(val.Bytes())) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /micro_v2/ecode/common_ecode.go: -------------------------------------------------------------------------------- 1 | package ecode 2 | 3 | var ( 4 | OK = add(0) // 正确 5 | 6 | RequestErr = add(-400) // 请求错误 7 | Unauthorized = add(-401) // 未认证 8 | AccessDenied = add(-403) // 访问权限不足 9 | NothingFound = add(-404) // 资源不存在 10 | MethodNotAllowed = add(-405) // 不支持该方法 11 | ParamErr = add(-406) // 参数错误 12 | Canceled = add(-498) // 客户端取消请求 13 | ServerErr = add(-500) // 服务器错误 14 | ServiceUnavailable = add(-503) // 过载保护,服务暂不可用 15 | Deadline = add(-504) // 服务调用超时 16 | LimitExceed = add(-509) // 超出限制 17 | ) 18 | 19 | func init() { 20 | cms := map[int]map[string]string{ 21 | ParamErr.Code(): { 22 | "cn": "你好世界", 23 | "en": "hello world", 24 | }, 25 | } 26 | Register(cms) 27 | } 28 | -------------------------------------------------------------------------------- /micro_v2/etcd_lock_test.go: -------------------------------------------------------------------------------- 1 | package test_agent 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "github.com/coreos/etcd/clientv3" 7 | "github.com/coreos/etcd/clientv3/concurrency" 8 | "testing" 9 | "time" 10 | ) 11 | 12 | func Lock() { 13 | config := clientv3.Config{ 14 | Endpoints: []string{"172.13.3.160:2379"}, 15 | DialTimeout: 5 * time.Second, 16 | } 17 | client, err := clientv3.New(config) 18 | if err != nil { 19 | panic(err) 20 | } 21 | defer client.Close() 22 | //创建一个20秒过期的锁 23 | session, err := concurrency.NewSession(client, concurrency.WithTTL(20)) 24 | if err != nil { 25 | panic(err) 26 | } 27 | timeout, cancel := context.WithTimeout(context.TODO(), time.Second*10) 28 | defer cancel() 29 | m := concurrency.NewMutex(session, "test-mutex") 30 | //10秒内不能获取到锁就不再获取 31 | if err := m.Lock(timeout); err != nil { 32 | fmt.Println("could not wait on lock ", err) 33 | } else { 34 | fmt.Println("获取到锁") 35 | } 36 | } 37 | 38 | func TestConcurrency(t *testing.T) { 39 | go Lock() 40 | go Lock() 41 | go Lock() 42 | select {} 43 | } 44 | -------------------------------------------------------------------------------- /micro_v2/go.mod: -------------------------------------------------------------------------------- 1 | module micro_v2 2 | 3 | go 1.14 4 | 5 | require ( 6 | github.com/coreos/etcd v3.3.18+incompatible 7 | github.com/golang/protobuf v1.4.2 8 | github.com/micro/go-micro/v2 v2.8.0 9 | github.com/pkg/errors v0.9.1 10 | ) 11 | -------------------------------------------------------------------------------- /micro_v2/make.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | protoc --micro_out=. --go_out=. *.proto -------------------------------------------------------------------------------- /micro_v2/test.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package test_agent; 3 | service Test { 4 | rpc RpcUserInfo (ReqMsg) returns (ResMsg) { 5 | } 6 | } 7 | 8 | message Error { 9 | int32 code = 1; 10 | string msg = 2; 11 | } 12 | 13 | message ReqMsg { 14 | string user_name = 1; 15 | } 16 | 17 | message ResMsg { 18 | Error error = 1; 19 | string info=2; 20 | } -------------------------------------------------------------------------------- /minio/minio_thumbnail/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "os" 5 | ) 6 | 7 | func main() { 8 | if err := app.Run(os.Args); err != nil { 9 | panic(err) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /mysql/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "database/sql" 5 | "fmt" 6 | ) 7 | import _ "github.com/go-sql-driver/mysql" //导入mysql驱动包" 8 | 9 | type User struct { 10 | Id int 11 | Name string 12 | } 13 | 14 | func main() { 15 | db, err := sql.Open("mysql", "root:howie@tcp(127.0.0.1:3306)/test?charset=utf8") 16 | if err != nil { 17 | panic(err) 18 | } 19 | var user []User 20 | rows, err := db.Query("select * from user") 21 | for rows.Next() { 22 | var Id int 23 | var Name string 24 | if err := rows.Scan(&Id, &Name); err != nil { 25 | continue 26 | } 27 | user = append(user, User{Id: Id, Name: Name}) 28 | 29 | } 30 | fmt.Println(user) 31 | //[{1 111111} {2 22222} {3 33333} {4 44444}] 32 | } 33 | -------------------------------------------------------------------------------- /network/ip.go: -------------------------------------------------------------------------------- 1 | package network 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | "strings" 7 | ) 8 | 9 | func GetIP() error { 10 | var err error 11 | var advt, host, port string 12 | advt = ":0" 13 | if cnt := strings.Count(advt, ":"); cnt >= 1 { 14 | // ipv6 address in format [host]:port or ipv4 host:port 15 | host, port, err = net.SplitHostPort(advt) 16 | if err != nil { 17 | return err 18 | } 19 | } else { 20 | host = advt 21 | } 22 | addr, err := Extract(host) 23 | if err != nil { 24 | return err 25 | } 26 | fmt.Println(HostPort(addr, port)) 27 | return nil 28 | } 29 | 30 | func HostPort(addr string, port interface{}) string { 31 | host := addr 32 | if strings.Count(addr, ":") > 0 { 33 | host = fmt.Sprintf("[%s]", addr) 34 | } 35 | // when port is blank or 0, host is a queue name 36 | if v, ok := port.(string); ok && v == "" { 37 | return host 38 | } else if v, ok := port.(int); ok && v == 0 && net.ParseIP(host) == nil { 39 | return host 40 | } 41 | 42 | return fmt.Sprintf("%s:%v", host, port) 43 | } 44 | -------------------------------------------------------------------------------- /network/ip_test.go: -------------------------------------------------------------------------------- 1 | package network 2 | 3 | import "testing" 4 | 5 | func TestGetIP(t *testing.T) { 6 | t.Log(GetIP()) 7 | } 8 | -------------------------------------------------------------------------------- /nsq/howie_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/nsqio/go-nsq" 5 | "log" 6 | "testing" 7 | "time" 8 | ) 9 | 10 | func TestPr(t *testing.T) { 11 | send("howie", "0.0.0.0:4150") 12 | send("howie", "0.0.0.0:4152") 13 | } 14 | 15 | func send(tag string, addr string) { 16 | config := nsq.NewConfig() 17 | p, err := nsq.NewProducer(addr, config) 18 | if err != nil { 19 | log.Println(err) 20 | return 21 | } 22 | p.Publish(tag, []byte(tag+":"+time.Now().String())) 23 | } 24 | -------------------------------------------------------------------------------- /nsq/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/nsqio/go-nsq" 6 | "log" 7 | "os" 8 | "os/signal" 9 | ) 10 | 11 | func main() { 12 | config := nsq.NewConfig() 13 | //最大允许向两台NSQD服务器接受消息,默认是1,要特别注意 14 | config.MaxInFlight = 2 15 | c, err := nsq.NewConsumer("howie", "hwholiday", config) 16 | if err != nil { 17 | log.Println(1) 18 | log.Println(err) 19 | return 20 | } 21 | c.AddHandler(nsq.HandlerFunc(func(msg *nsq.Message) error { 22 | fmt.Println(string(msg.Body)) 23 | return nil 24 | })) 25 | if err = c.ConnectToNSQLookupd("0.0.0.0:4161"); err != nil { 26 | log.Fatalln(2) 27 | log.Fatalln(err) 28 | return 29 | } 30 | ch := make(chan os.Signal, 1) 31 | signal.Notify(ch, os.Interrupt, os.Kill) 32 | <-ch 33 | } 34 | -------------------------------------------------------------------------------- /other/00_ff_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math/rand" 6 | "testing" 7 | "time" 8 | ) 9 | 10 | //可以作为 hbase rowkey 前置补0 11 | func TestFF(t *testing.T) { 12 | rand.Seed(time.Now().Unix()) 13 | for i := 1; i <= 256; i++ { 14 | a := fmt.Sprintf("%02x", rand.Intn(256)) 15 | t.Log(a) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /other/README.md: -------------------------------------------------------------------------------- 1 | ### go test -v json_test.go -test.run TestJsonV1 2 | -------------------------------------------------------------------------------- /other/binaryFind_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestBinaryFind(t *testing.T) { 8 | var sortedArray []int = []int{1, 3, 4, 6, 7, 9, 10, 11, 13} 9 | t.Log(BinaryFind(sortedArray, 6)) 10 | } 11 | 12 | func BinaryFind(array []int, find int) (val int) { 13 | var ( 14 | leaf = 0 15 | right = len(array) 16 | ) 17 | for leaf <= right { 18 | mod := (leaf + right) / 2 19 | modVal := array[mod] 20 | if modVal > find { 21 | right = mod - 1 22 | } else if modVal < find { 23 | leaf = mod + 1 24 | } else { 25 | return mod 26 | } 27 | } 28 | return -1 29 | } 30 | -------------------------------------------------------------------------------- /other/qsort_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func Test_QSORT(t *testing.T) { 9 | a := []int{-1, 0, 1, 2, -1, -4, -5} 10 | qsort(a) 11 | fmt.Println(a) 12 | t.Log(a) 13 | } 14 | 15 | func qsort(array []int) { 16 | if len(array) <= 1 { 17 | return 18 | } 19 | var ( 20 | left = 0 21 | right = len(array) - 1 22 | ) 23 | mod := array[0] 24 | for left < right { 25 | if mod > array[left+1] { 26 | array[left+1], array[left] = array[left], array[left+1] 27 | left++ 28 | } else { 29 | array[left+1], array[right] = array[right], array[left+1] 30 | right-- 31 | } 32 | } 33 | qsort(array[:left]) 34 | qsort(array[left+1:]) 35 | } 36 | -------------------------------------------------------------------------------- /other/t_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | type Num interface { 9 | int64 | float64 10 | } 11 | 12 | func TestT(t *testing.T) { 13 | ints := map[string]int64{ 14 | "first": 34, 15 | "second": 12, 16 | } 17 | fmt.Println(SumIntsOrFloats[string, int64](ints)) 18 | fmt.Println(SumNum(ints)) 19 | } 20 | func SumIntsOrFloats[K comparable, V int64 | float64](m map[K]V) V { 21 | var s V 22 | for _, v := range m { 23 | s += v 24 | } 25 | return s 26 | } 27 | func SumNum[K comparable, V Num](m map[K]V) V { 28 | var s V 29 | for _, v := range m { 30 | s += v 31 | } 32 | return s 33 | } 34 | -------------------------------------------------------------------------------- /other/trie_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "testing" 4 | 5 | func TestTrie(t *testing.T) { 6 | 7 | } 8 | 9 | type Trie struct { 10 | next map[string]*Trie 11 | isEnd bool 12 | } 13 | 14 | func NewTrie() *Trie { 15 | trie := new(Trie) 16 | trie.isEnd = false 17 | trie.next = make(map[string]*Trie) 18 | return trie 19 | } 20 | -------------------------------------------------------------------------------- /prometheus/howie_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "testing" 7 | "time" 8 | ) 9 | 10 | func Test(t *testing.T) { 11 | for { 12 | time.Sleep(50 * time.Millisecond) 13 | send() 14 | } 15 | time.Sleep(24 * time.Hour) 16 | } 17 | func send() { 18 | resp, err := http.Get("http://192.168.2.28:8888/howie") 19 | if err != nil { 20 | fmt.Println(err) 21 | return 22 | } 23 | resp.Body.Close() 24 | } 25 | -------------------------------------------------------------------------------- /proxy/proxy_http/proxy.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "net/http/httputil" 7 | "net/url" 8 | ) 9 | 10 | func main() { 11 | mu := http.NewServeMux() 12 | mu.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) { 13 | remote, err := url.Parse("http://127.0.0.1:8881") 14 | if err != nil { 15 | panic(err) 16 | } 17 | fmt.Println("accept request") 18 | proxy := httputil.NewSingleHostReverseProxy(remote) 19 | proxy.ServeHTTP(writer, request) 20 | }) 21 | fmt.Println("proxy server success :", 8880) 22 | _ = http.ListenAndServe(":8880", mu) 23 | } 24 | -------------------------------------------------------------------------------- /proxy/proxy_http/server/service.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | ) 7 | 8 | func main() { 9 | mu := http.NewServeMux() 10 | mu.HandleFunc("/test", func(writer http.ResponseWriter, request *http.Request) { 11 | fmt.Println("test request") 12 | _, _ = writer.Write([]byte("test success")) 13 | }) 14 | fmt.Println("server success :", 8881) 15 | _ = http.ListenAndServe(":8881", mu) 16 | } 17 | -------------------------------------------------------------------------------- /push/handler/msg.go: -------------------------------------------------------------------------------- 1 | package handler 2 | 3 | //服务端上报数据 4 | type ServerReport struct { 5 | Uid int `json:"uid"` 6 | Msg string `json:"msg"` 7 | Sign string `json:"sign"` 8 | } 9 | 10 | //客户端上报 11 | type ClientsReport struct { 12 | Uid int `json:"uid"` 13 | Status int `json:"status"` //1心跳包,2其他 14 | Msg string `json:"msg"` 15 | } 16 | -------------------------------------------------------------------------------- /push/handler/tcp_handler.go: -------------------------------------------------------------------------------- 1 | package handler 2 | 3 | import ( 4 | "encoding/json" 5 | "io/ioutil" 6 | "net/http" 7 | ) 8 | 9 | var pushChan = make(chan bool, 50) 10 | 11 | func ReportHandler(w http.ResponseWriter, r *http.Request) { 12 | if r.Method != "POST" { 13 | w.Write([]byte("请使用POST方法")) 14 | return 15 | } 16 | pushChan <- true 17 | defer func() { 18 | <-pushChan 19 | }() 20 | reqData, err := ioutil.ReadAll(r.Body) 21 | if err != nil { 22 | w.Write([]byte(err.Error())) 23 | return 24 | } 25 | var report ServerReport 26 | if err := json.Unmarshal(reqData, &report); err != nil { 27 | w.Write([]byte(err.Error())) 28 | return 29 | } 30 | if report.Uid == 0 || report.Msg == "" || report.Sign == "" { 31 | w.Write([]byte("参数不完整")) 32 | return 33 | } 34 | if err := PushMsg(report.Uid, report.Msg); err != nil { 35 | w.Write([]byte(err.Error())) 36 | return 37 | } 38 | w.Write([]byte("ok")) 39 | return 40 | 41 | } 42 | -------------------------------------------------------------------------------- /push/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "net/http" 7 | _ "net/http/pprof" 8 | "test/push/handler" 9 | ) 10 | 11 | var ( 12 | Addr = "127.0.0.1:8182" 13 | ) 14 | 15 | func main() { 16 | addr := flag.String("addr", "127.0.0.1:8182", "addr") 17 | flag.Parse() 18 | go handler.H.Run() 19 | http.HandleFunc("/v1/push", handler.PushHandler) 20 | http.HandleFunc("/v1/report", handler.ReportHandler) 21 | fmt.Printf("Chat Run :%s", *addr) 22 | if err := http.ListenAndServe(*addr, nil); err != nil { 23 | fmt.Printf("WebSocker:%s", err.Error()) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /quic/ca.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICxjCCAa4CCQCjhcoNf4zvIzANBgkqhkiG9w0BAQsFADAlMSMwIQYDVQQKDBpx 3 | dWljIENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0yMjA2MDgxNzQxNTBaFw0zMjA2 4 | MDUxNzQxNTBaMCUxIzAhBgNVBAoMGnF1aWMgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 5 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvVZ9G0lkSQ+Fir4wW33x 6 | TAos1jdC3TsA1knrsQa7KBHhu2rIuPIzsjwm4frfZW33O2Nz1wI7a1pVe/tPKlI+ 7 | APX9aOa26tzKtp3w9AVOC5zyvV1H0oP90pc1/YZeWhxoDj6XoF/gkuFfBvk9blw3 8 | ZOH4eakqEphWuIRpBYWohl340P7R++lDJUyw73MdWkf7HHBPYn8QSoY8b2aJ5fCp 9 | wRmFU3sY15kerEhTK9GobHsAvIdOyebr2AaKHqcsnkmowSfZpf4P2fd1Hv8PHisY 10 | mR9a/ivobSWXFrEAfqPYjjJWhoE7aitF52uiJBmAU86paRtWU6TfXAeaLSQ847Pg 11 | 5QIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQC6T1woPAhlFnGX1JnXs9gnaA6c5gVY 12 | M62TnkL9ksBtcItohbkvKiyfceAN+PwmupM+R5/e5KyU3hkZvbzy0jMeIAAJs7ec 13 | iyTVr/98rlyxYMnX6cvMEPQ7+Oc6kRxQmJr/ORJ7QF+uj+D0dyUjoaViu29HWw0Z 14 | 5I1tcxytb672FGPBLWj+2b2O4HMHEh25840MhKjuSJ8xWTeLjzy0yWEoamovaLpv 15 | /XdTwoSpOBI5rzURg+LQuyNQO/yveUljBYWjn4utP3ooGIjs64JZnoYkLXH5jThl 16 | spjrq+Y8Q1QSK2DdnUAGw+DXuZRS1MN/ZjtzF6IoAt8BjbRqKux3ITNh 17 | -----END CERTIFICATE----- 18 | -------------------------------------------------------------------------------- /quic/cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICzzCCAbegAwIBAgIJAL6Vw7VkraKHMA0GCSqGSIb3DQEBCwUAMCUxIzAhBgNV 3 | BAoMGnF1aWMgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTIyMDYwODE3NDE1MFoX 4 | DTMyMDYwNTE3NDE1MFowDzENMAsGA1UECgwEcXVpYzCCASIwDQYJKoZIhvcNAQEB 5 | BQADggEPADCCAQoCggEBAMgWz5PvtvL5Izm5AawQKVwW24sZ30Y0PQn0o1zRJSYt 6 | QwwtFBDuSqxfuysQFioBEZAIOQUt8cKllOm+8pehQT50lBfM9CsukYKVDOkmbdLN 7 | 65l5Z9MfZptElrk7WtecPylk3l8Tg9Q8VEDby82pkN8P/1UiY5x53NsGuzQFSTqm 8 | n1SiFXq2g1vrAxxIppi73WtrlyePKwmmkUbOza/TF766f8QVleCGBbhzipYnaWfg 9 | EW978l4LI0dMoZcYntVSY3X3Dl1Pgt8gMBKwVlKtDKudQBSPWSkFjnmgMGkftYFi 10 | iW8hzTZ5ZOAYT7QHWLTegzCoTVGY4AaIw+u7/hZPQK0CAwEAAaMYMBYwFAYDVR0R 11 | BA0wC4IJbG9jYWxob3N0MA0GCSqGSIb3DQEBCwUAA4IBAQCaSrOyPwYyu58BrZ9U 12 | 7XPD7Q7qYwAABewcdXB8zwEzusUdKUwOMHsTCsxt6PvYmv+5PClOZkXIPkwdS4bd 13 | DEn2tdcjk+VFYqUZ/Z/LWNOuW5YBdvfgNZURChrKQE3g/oOSCkL1g57IS/IbZ/ow 14 | c7b/LNN/mJ75Jy0zrc4JLUbulIqQ5+lLCnkEacwISAFopWwXCWa67V6AM5T0/tPR 15 | 2XteaABGOzTU3XziP+MUp0U7yRkqvTICUObbfVljDpptMMOsp1Hp4+TxQmP7wSMS 16 | EvSGH8RKNsyiA9hD7VlO5l17yw3ChqYh0PL+IVfXU2Xl1mi+W7zFJPs3e7rNN+Ve 17 | 5KDI 18 | -----END CERTIFICATE----- 19 | -------------------------------------------------------------------------------- /quic/generate_key.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | echo "Generating CA key and certificate:" 6 | openssl req -x509 -sha256 -nodes -days 3650 -newkey rsa:2048 \ 7 | -keyout ca.key -out ca.pem \ 8 | -subj "/O=quic Certificate Authority/" 9 | 10 | echo "Generating CSR" 11 | openssl req -out cert.csr -new -newkey rsa:2048 -nodes -keyout priv.key \ 12 | -subj "/O=quic/" 13 | 14 | echo "Sign certificate:" 15 | openssl x509 -req -sha256 -days 3650 -in cert.csr -out cert.pem \ 16 | -CA ca.pem -CAkey ca.key -CAcreateserial \ 17 | -extfile <(printf "subjectAltName=DNS:localhost") 18 | 19 | # debug output the certificate 20 | openssl x509 -noout -text -in cert.pem 21 | 22 | # we don't need the CA key, the serial number and the CSR any more 23 | rm ca.key cert.csr ca.srl 24 | 25 | -------------------------------------------------------------------------------- /quic/quic_server.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | 7 | "github.com/lucas-clemente/quic-go" 8 | 9 | "github.com/lucas-clemente/quic-go/http3" 10 | 11 | "github.com/google/uuid" 12 | ) 13 | 14 | const ( 15 | addr = ":8888" 16 | ) 17 | 18 | func main() { 19 | setUpQuic() 20 | } 21 | 22 | func setUpQuic() { 23 | mux := http.NewServeMux() 24 | mux.HandleFunc("/quic", func(w http.ResponseWriter, r *http.Request) { 25 | fmt.Printf("request %+v \n", r.Header) 26 | _, _ = w.Write([]byte(uuid.New().String())) 27 | }) 28 | 29 | server := http3.Server{ 30 | Server: &http.Server{Handler: mux, Addr: addr}, 31 | QuicConfig: &quic.Config{}, 32 | } 33 | fmt.Println("start http3 quic addr " + addr) 34 | if err := server.ListenAndServeTLS("./cert.pem", "./priv.key"); err != nil { 35 | panic(err) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /redis/bitmap_filter/bitmap_test.go: -------------------------------------------------------------------------------- 1 | package bitmap_filter 2 | 3 | import ( 4 | "github.com/go-redis/redis" 5 | "testing" 6 | ) 7 | 8 | func Test_hashKey(t *testing.T) { 9 | d := "0x0a0f824b9e1e951560d9fa1fd4b89403d092d046" 10 | t.Log(hashKey(d)) 11 | } 12 | 13 | func TestNewBitMapFileTer(t *testing.T) { 14 | r := redis.NewClient(&redis.Options{ 15 | Addr: "172.12.12.165:6379", 16 | }) 17 | b := NewBitMapFileTer(r, "gs_bitmap") 18 | t.Log(b.Add("0x0a0f824b9e1e951560d9fa1fd4b89403d092d046")) 19 | t.Log(b.Exist("0x0a0f824b9e1e951560d9fa1fd4b89403d092d0461")) 20 | } 21 | -------------------------------------------------------------------------------- /redis/lock/lock_server.go: -------------------------------------------------------------------------------- 1 | package lock 2 | 3 | type RedisLockServer interface { 4 | TryLock() error 5 | UnLock() error 6 | GetLockKey() string 7 | GetLockVal() string 8 | } 9 | -------------------------------------------------------------------------------- /redis/lock/lock_test.go: -------------------------------------------------------------------------------- 1 | package lock 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "github.com/go-redis/redis" 7 | "testing" 8 | "time" 9 | ) 10 | 11 | func TestRedis(t *testing.T) { 12 | GlobalClient := redis.NewClient( 13 | &redis.Options{ 14 | Addr: "172.12.12.165:6379", 15 | DialTimeout: 10 * time.Second, 16 | ReadTimeout: 30 * time.Second, 17 | WriteTimeout: 30 * time.Second, 18 | Password: "", 19 | PoolSize: 10, 20 | DB: 0, 21 | }, 22 | ) 23 | ping, err := GlobalClient.Ping(context.Background()).Result() 24 | if nil != err { 25 | panic(err) 26 | } 27 | fmt.Println("ping", ping) 28 | redisLock := NewRedisLock(GlobalClient, "test", "1", time.Second*3) 29 | InitRedis(redisLock) 30 | select {} 31 | } 32 | func InitRedis(lock RedisLockServer) { 33 | go func() { 34 | for { 35 | time.Sleep(time.Second) 36 | err := lock.TryLock() 37 | if err != nil { 38 | fmt.Println("获取锁失败") 39 | } else { 40 | fmt.Println("获取锁成功") 41 | } 42 | } 43 | }() 44 | } 45 | -------------------------------------------------------------------------------- /redis/subscription/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/garyburd/redigo/redis" 6 | "time" 7 | ) 8 | 9 | func main() { 10 | 11 | c, err := redis.Dial("tcp", "127.0.0.1:6379") 12 | CheckErr(err) 13 | psc := redis.PubSubConn{c} 14 | psc.Subscribe("howie") 15 | go func() { 16 | for { 17 | time.Sleep(3 * time.Second) 18 | publish("127.0.0.1:6379") 19 | } 20 | }() 21 | for { 22 | switch v := psc.Receive().(type) { 23 | case redis.Subscription: 24 | fmt.Printf("1 %s: %s %d\n", v.Channel, v.Kind, v.Count) 25 | break 26 | case redis.Message: //单个订阅subscribe 27 | fmt.Printf("2 %s: message: %s\n", v.Channel, v.Data) 28 | break 29 | case error: 30 | fmt.Println(v) 31 | break 32 | } 33 | } 34 | 35 | } 36 | func CheckErr(err error) { 37 | if err != nil { 38 | panic(err) 39 | } 40 | } 41 | 42 | func publish(redisServerAddr string) { 43 | c, err := redis.Dial("tcp", redisServerAddr) 44 | if err != nil { 45 | fmt.Println(err) 46 | return 47 | } 48 | defer c.Close() 49 | c.Do("PUBLISH", "howie", "hello") 50 | } 51 | -------------------------------------------------------------------------------- /req_limit/howie_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "net/http" 5 | "testing" 6 | ) 7 | 8 | func TestLimit(t *testing.T) { 9 | for i := 0; i < 2; i++ { 10 | go func() { 11 | for { 12 | _, err := http.Get("http://192.168.2.28:8099/limit_api_v1") 13 | if err != nil { 14 | panic(err) 15 | } 16 | } 17 | }() 18 | } 19 | select {} 20 | } 21 | -------------------------------------------------------------------------------- /req_limit/uber_ratelimit_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "go.uber.org/ratelimit" 6 | "testing" 7 | "time" 8 | ) 9 | 10 | func TestRateLimitV1(t *testing.T) { 11 | limit := ratelimit.New(100) //每秒100个请求 12 | prev := time.Now() 13 | for i := 0; i < 10; i++ { 14 | now := limit.Take() 15 | if i == 3 { 16 | time.Sleep(time.Millisecond * 16) 17 | } 18 | fmt.Println(i, now.Sub(prev)) 19 | prev = now 20 | } 21 | } 22 | 23 | func TestRateLimitV2(t *testing.T) { 24 | limit := ratelimit.New(100, ratelimit.WithoutSlack) //每秒100个请求 WithoutSlack来取消松弛量 25 | prev := time.Now() 26 | for i := 0; i < 10; i++ { 27 | now := limit.Take() 28 | fmt.Println(i, now.Sub(prev)) 29 | prev = now 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /rocketmq/README.md: -------------------------------------------------------------------------------- 1 | #### docker run --name rmqnamesrv -d -p 9876:9876 rocketmqinc/rocketmq:latest sh mqnamesrv 2 | 3 | 4 | 5 | #### broker.conf 6 | ```base 7 | terName = DefaultCluster 8 | brokerName = broker-a 9 | brokerId = 0 10 | deleteWhen = 04 11 | fileReservedTime = 48 12 | brokerRole = ASYNC_MASTER 13 | flushDiskType = ASYNC_FLUSH 14 | brokerIP1 = 172.13.3.160 15 | autoCreateTopicEnable=true 16 | ``` 17 | 18 | 19 | #### docker run --name rmqbroker -d -p 10911:10911 -p 10909:10909 --link rmqnamesrv:namesrv -e "NAMESRV_ADDR=namesrv:9876" -v /root/docker_data/broker.conf:/opt/rocketmq/conf/broker.conf rocketmqinc/rocketmq:latest sh mqbroker -c /opt/rocketmq/conf/broker.conf 20 | 21 | 22 | 23 | #### docker run --name rmqconsole -d -p 8080:8080 --link rmqnamesrv:namesrv -e "JAVA_OPTS=-Drocketmq.namesrv.addr=namesrv:9876" pangliang/rocketmq-console-ng -------------------------------------------------------------------------------- /rocketmq/go.mod: -------------------------------------------------------------------------------- 1 | module learning_tools/rocketmq 2 | 3 | go 1.15 4 | 5 | require github.com/apache/rocketmq-client-go/v2 v2.1.0-rc5 6 | -------------------------------------------------------------------------------- /rocksdb/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.17 2 | 3 | ARG ROCKSDB_VERSION=v7.9.2 4 | 5 | RUN apk update && \ 6 | apk add --no-cache zlib-dev bzip2-dev lz4-dev snappy-dev zstd-dev gflags-dev && \ 7 | apk add --no-cache build-base linux-headers git bash perl && \ 8 | mkdir /usr/src && \ 9 | cd /usr/src && \ 10 | git clone --depth 1 --branch ${ROCKSDB_VERSION} https://github.com/facebook/rocksdb.git && \ 11 | cd /usr/src/rocksdb && \ 12 | sed -i 's/install -C/install -c/g' Makefile && \ 13 | make -j4 shared_lib && \ 14 | make install-shared && \ 15 | apk del build-base linux-headers git bash perl && \ 16 | rm -rf /usr/src/rocksdb 17 | 18 | WORKDIR / -------------------------------------------------------------------------------- /rocksdb/rocksdb.md: -------------------------------------------------------------------------------- 1 | ### 安装 rocksdb -------------------------------------------------------------------------------- /rpc/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "learning_tools/all_packaged_library/perf" 6 | "learning_tools/all_packaged_library/quit" 7 | "net" 8 | "net/rpc" 9 | ) 10 | 11 | // RPC 12 | type RPC struct { 13 | auther string 14 | } 15 | 16 | type Arg struct { 17 | Arg string 18 | } 19 | 20 | type Reply struct { 21 | Reply string 22 | } 23 | 24 | func main() { 25 | perf.StartPprof([]string{"192.168.2.28:9022"}) 26 | rpc.Register(&RPC{auther: "111111"}) 27 | go rpcListen("tcp", "192.168.2.28:9023") 28 | quit.QuitSignal(func() { 29 | fmt.Println("开始退出") 30 | fmt.Println("退出程序") 31 | }) 32 | } 33 | 34 | func rpcListen(network, addr string) { 35 | l, err := net.Listen(network, addr) 36 | if err != nil { 37 | panic(err) 38 | } 39 | defer func() { 40 | if err := l.Close(); err != nil { 41 | panic(err) 42 | } 43 | }() 44 | rpc.Accept(l) 45 | } 46 | 47 | func (r *RPC) Ping(arg *Arg, reply *Reply) error { 48 | reply.Reply = arg.Arg + "howie" 49 | return nil 50 | } 51 | -------------------------------------------------------------------------------- /rpc/rpc_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/rpc" 6 | "testing" 7 | ) 8 | 9 | func Test(t *testing.T) { 10 | client, err := rpc.Dial("tcp", "192.168.2.28:9023") 11 | if err != nil { 12 | panic(err) 13 | } 14 | var ( 15 | arg = Arg{Arg: "coco"} 16 | reply = Reply{} 17 | ) 18 | err = client.Call("RPC.Ping", &arg, &reply) 19 | if err != rpc.ErrShutdown { 20 | client.Close() 21 | } 22 | fmt.Println(reply) 23 | } 24 | -------------------------------------------------------------------------------- /service_load_balancing/fisher_yates_test.go: -------------------------------------------------------------------------------- 1 | package service_load_balancing 2 | 3 | import ( 4 | "math/rand" 5 | "testing" 6 | "time" 7 | ) 8 | 9 | var endpoints = []string{ 10 | "127.0.0.1:80", 11 | "127.0.0.2:80", 12 | "127.0.0.3:80", 13 | "127.0.0.4:80", 14 | "127.0.0.5:80", 15 | "127.0.0.6:80", 16 | "127.0.0.7:80", 17 | } 18 | 19 | //从数学上得到过证明的还是经典的fisher-yates算法,主要思路为每次随机挑选一个值,放在数组末尾。然后在n-1个元素的数组中再随机挑选一个值,放在数组末尾,以此类推。 20 | func fisher_yates(slice []int) { 21 | rand.Seed(time.Now().UnixNano()) 22 | for i := len(slice); i > 0; i-- { 23 | lastIdx := i - 1 24 | idx := rand.Intn(i) 25 | slice[lastIdx], slice[idx] = slice[idx], slice[lastIdx] 26 | } 27 | } 28 | 29 | func TestShuffle(t *testing.T) { 30 | var indexArray = make([]int, 0, len(endpoints)) 31 | for i := 0; i < len(endpoints); i++ { 32 | indexArray = append(indexArray, i) 33 | } 34 | t.Log("索引数组", indexArray) 35 | for i := 0; i < 10; i++ { 36 | fisher_yates(indexArray) 37 | t.Log("fisher_yates 后选择的负载均衡节点信息", endpoints[indexArray[0]]) 38 | 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /syncPool/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "sync" 6 | ) 7 | 8 | func main() { 9 | // 建立对象 10 | var pipe = &sync.Pool{New: func() interface{} { return "Hello" }} 11 | // 准备放入的字符串 12 | val := "Hello,World!" 13 | // 放入 14 | pipe.Put(val) 15 | // 取出 16 | log.Println(pipe.Get()) 17 | // 再取就没有了,会自动调用NEW 18 | log.Println(pipe.Get()) 19 | 20 | } 21 | -------------------------------------------------------------------------------- /tcp/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "learning_tools/all_packaged_library/perf" 6 | "learning_tools/all_packaged_library/quit" 7 | "learning_tools/tcp/network" 8 | ) 9 | 10 | func main() { 11 | perf.StartPprof([]string{"192.168.2.28:9022"}) 12 | go network.InitTcp() 13 | quit.QuitSignal(func() { 14 | fmt.Println("开始退出") 15 | fmt.Println("退出程序") 16 | }) 17 | } 18 | -------------------------------------------------------------------------------- /timewheel/timewheel_test.go: -------------------------------------------------------------------------------- 1 | package timewheel 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | "time" 7 | ) 8 | 9 | func TestAddTask(t *testing.T) { 10 | tw := DefaultTimeWheel() 11 | err := tw.AddTask("task-1", func(key string) { 12 | fmt.Println("task run :", key, " > ", time.Now().Format(time.DateTime)) 13 | }, 3*time.Second, 6) 14 | t.Log("err", err) 15 | //time.Sleep(time.Second * 3) 16 | //tw.Stop() 17 | //tw.RemoveTask("task-1") 18 | time.Sleep(time.Hour) 19 | } 20 | -------------------------------------------------------------------------------- /tool/binary_conversion/10to36.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | ) 7 | 8 | func main() { 9 | data := strconv.FormatUint(212121212, 36) //10进制转36进制 10 | fmt.Println(data) 11 | fmt.Println(strconv.ParseUint(data, 36, 64)) //36进制转10进制 12 | } 13 | -------------------------------------------------------------------------------- /tool/binary_conversion/binary.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | var switchs uint64 7 | fmt.Printf("%064b\n", switchs) 8 | switchs = 1<<63 | 1<<2 | 1<<3 //直接替换 9 | fmt.Printf("%064b\n", switchs) 10 | switchs = 1 << 0 11 | fmt.Printf("%064b\n", switchs) 12 | switchs = 1<<62 | 1<<61 | 1<<60 //修改某一些的东西 13 | fmt.Printf("%064b\n", switchs) 14 | fmt.Println(switchs) 15 | fmt.Printf("%064b\n", 1<<62) 16 | fmt.Printf("%064b\n", 8070450532247928832) 17 | fmt.Println(1 << 2 & 8070450532247928832) //判断第二位是不是0 18 | fmt.Println(1 << 62 & 8070450532247928832) //判断第二位是不是0 19 | fmt.Println(1 << 1 & 8070450532247928832) //判断第二位是不是0 20 | } 21 | -------------------------------------------------------------------------------- /tool/decimal/decimal.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/shopspring/decimal" 6 | ) 7 | 8 | func main() { 9 | if f, ok := decimal.NewFromInt(136668569852182528).Float64(); ok { 10 | fmt.Println(f) 11 | } 12 | 13 | price, err := decimal.NewFromString("136.02") 14 | if err != nil { 15 | panic(err) 16 | } 17 | quantity := decimal.NewFromInt(3) 18 | 19 | fee, _ := decimal.NewFromString(".035") 20 | taxRate, _ := decimal.NewFromString(".08875") 21 | 22 | subtotal := price.Mul(quantity) 23 | 24 | preTax := subtotal.Mul(fee.Add(decimal.NewFromFloat(1))) 25 | 26 | total := preTax.Mul(taxRate.Add(decimal.NewFromFloat(1))) 27 | 28 | fmt.Println("Subtotal:", subtotal) // Subtotal: 408.06 29 | fmt.Println("Pre-tax:", preTax) // Pre-tax: 422.3421 30 | fmt.Println("Taxes:", total.Sub(preTax)) // Taxes: 37.482861375 31 | fmt.Println("Total:", total) // Total: 459.824961375 32 | fmt.Println("Tax rate:", total.Sub(preTax).Div(preTax)) // Tax rate: 0.08875 33 | } 34 | -------------------------------------------------------------------------------- /websocket/cmd/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/hwholiday/learning_tools/websocket/gateway/ws" 5 | ) 6 | 7 | func main() { 8 | ws.InitWsServer() 9 | select {} 10 | } 11 | -------------------------------------------------------------------------------- /websocket/gateway/msg/errors.go: -------------------------------------------------------------------------------- 1 | package msg 2 | 3 | import "errors" 4 | 5 | var ( 6 | ErrMsgNotProto = errors.New("msg not proto") 7 | ErrProtocol = errors.New("protocol too much") 8 | ErrNotRegister = errors.New("protocol not register") 9 | ErrMsgShort = errors.New("msg too short") 10 | ) 11 | 12 | var ( 13 | ErrExceedMaxConn = errors.New("maximum connections exceeded") 14 | ) 15 | -------------------------------------------------------------------------------- /websocket/gateway/msg/msg_test.go: -------------------------------------------------------------------------------- 1 | package msg 2 | 3 | import ( 4 | "os" 5 | "testing" 6 | 7 | "github.com/hwholiday/learning_tools/websocket/pb" 8 | ) 9 | 10 | func TestMain(m *testing.M) { 11 | NewMsgProtocol(true) 12 | os.Exit(m.Run()) 13 | } 14 | 15 | func TestNewMsgProtocol(t *testing.T) { 16 | p := GetMsgProtocol() 17 | p.Register(&pb.Ping{}, 1) 18 | data, err := p.Marshal(&pb.Ping{Times: 1}) 19 | if err != nil { 20 | t.Error(err) 21 | } 22 | info, err := p.Unmarshal(data) 23 | if err != nil { 24 | t.Error(err) 25 | } 26 | t.Log(info.(*pb.Ping)) 27 | } 28 | -------------------------------------------------------------------------------- /websocket/gateway/ws/ws_handle.go: -------------------------------------------------------------------------------- 1 | package ws 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | 7 | "github.com/hwholiday/learning_tools/websocket/pb" 8 | ) 9 | 10 | func wsHandle(w *WsConnection) { 11 | var ( 12 | err error 13 | msg interface{} 14 | ) 15 | fmt.Println("开启链接: ", w.GetIp(), "UID", w.GetUid(), "WSID", w.GetWsId()) 16 | for { 17 | if msg, err = w.ReadMsg(); err != nil { 18 | wsClose(w) 19 | return 20 | } 21 | switch msg.(type) { 22 | case *pb.Ping: 23 | fmt.Println("*pb.Ping", msg.(*pb.Ping)) 24 | _ = w.ws.SetReadDeadline(time.Now().Add(time.Second * 20)) 25 | _ = w.SendMsg(&pb.Pong{ 26 | Times: time.Now().Unix(), 27 | }) 28 | } 29 | } 30 | } 31 | 32 | func wsClose(w *WsConnection) { 33 | w.close() 34 | } 35 | -------------------------------------------------------------------------------- /websocket/pb/msg.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package gateway; 3 | //错误码 4 | enum STATUS { 5 | //1~99, 通用错误码 6 | SUCCESS = 0; 7 | UNKNOWN_ERROR = 2; // 未知错误 8 | } 9 | // id 小于20的为保留协议 业务协议不能占用 10 | //id = 1 11 | message Ping{ 12 | int64 Times = 1; 13 | } 14 | 15 | //id = 2 16 | message Pong{ 17 | int64 Times = 1; 18 | } 19 | 20 | //id = 3 通用错误协议 21 | message ErrorEx { 22 | STATUS status = 1; 23 | string Msg = 2; 24 | int64 Times = 3; 25 | } 26 | -------------------------------------------------------------------------------- /wire/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | m := NewApp() 5 | m.Start() 6 | } 7 | -------------------------------------------------------------------------------- /wire/test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type Msg string 6 | 7 | type Msg2 struct { 8 | m Msg 9 | } 10 | 11 | type Msg3 struct { 12 | m Msg2 13 | } 14 | 15 | func NewMsg() Msg { 16 | return Msg("123") 17 | } 18 | 19 | func NewMsg2(m Msg) Msg2 { 20 | return Msg2{ 21 | m: m, 22 | } 23 | } 24 | 25 | func NewMsg3(m Msg2) Msg3 { 26 | return Msg3{ 27 | m: m, 28 | } 29 | } 30 | func (m Msg3) Start() { 31 | fmt.Println("111") 32 | } 33 | -------------------------------------------------------------------------------- /wire/wire.go: -------------------------------------------------------------------------------- 1 | //go:build wireinject 2 | // +build wireinject 3 | 4 | package main 5 | 6 | import "github.com/google/wire" 7 | 8 | func NewApp() Msg3 { 9 | wire.Build(NewMsg3, NewMsg2, NewMsg) 10 | return Msg3{} 11 | } 12 | -------------------------------------------------------------------------------- /wire/wire_gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by Wire. DO NOT EDIT. 2 | 3 | //go:generate wire 4 | //go:build !wireinject 5 | // +build !wireinject 6 | 7 | package main 8 | 9 | // Injectors from wire.go: 10 | 11 | func NewApp() Msg3 { 12 | msg := NewMsg() 13 | msg2 := NewMsg2(msg) 14 | msg3 := NewMsg3(msg2) 15 | return msg3 16 | } 17 | --------------------------------------------------------------------------------