{"id":42502857,"url":"https://github.com/buptmiao/microservice-app","last_synced_at":"2026-01-28T13:31:53.188Z","repository":{"id":87164032,"uuid":"75206428","full_name":"buptmiao/microservice-app","owner":"buptmiao","description":"A  microservices architecture app powered by golang.","archived":false,"fork":false,"pushed_at":"2017-12-11T11:14:04.000Z","size":1006,"stargazers_count":123,"open_issues_count":1,"forks_count":40,"subscribers_count":18,"default_branch":"master","last_synced_at":"2024-11-14T13:44:17.006Z","etag":null,"topics":["docker","etcd","gokit","golang","kubernetes","microservices","opentracing","prometheus","vagrant"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/buptmiao.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2016-11-30T16:39:09.000Z","updated_at":"2024-08-04T08:57:14.000Z","dependencies_parsed_at":null,"dependency_job_id":"9163306e-0098-450d-9b57-04ee84e3cf3e","html_url":"https://github.com/buptmiao/microservice-app","commit_stats":{"total_commits":13,"total_committers":1,"mean_commits":13.0,"dds":0.0,"last_synced_commit":"896651eb6dabb0fc876a3865ca472f416b5e5e05"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/buptmiao/microservice-app","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/buptmiao%2Fmicroservice-app","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/buptmiao%2Fmicroservice-app/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/buptmiao%2Fmicroservice-app/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/buptmiao%2Fmicroservice-app/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/buptmiao","download_url":"https://codeload.github.com/buptmiao/microservice-app/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/buptmiao%2Fmicroservice-app/sbom","scorecard":{"id":258495,"data":{"date":"2025-08-11","repo":{"name":"github.com/buptmiao/microservice-app","commit":"896651eb6dabb0fc876a3865ca472f416b5e5e05"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.5,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/13 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact v1.0.1 not signed: https://api.github.com/repos/buptmiao/microservice-app/releases/4878212","Warn: release artifact v1.0.1 does not have provenance: https://api.github.com/repos/buptmiao/microservice-app/releases/4878212"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: containerImage not pinned by hash: docker/Dockerfile.apigateway:1","Warn: containerImage not pinned by hash: docker/Dockerfile.feed:1","Warn: containerImage not pinned by hash: docker/Dockerfile.profile:1","Warn: containerImage not pinned by hash: docker/Dockerfile.topic:1","Info:   0 out of   4 containerImage dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}}]},"last_synced_at":"2025-08-17T10:13:26.509Z","repository_id":87164032,"created_at":"2025-08-17T10:13:26.509Z","updated_at":"2025-08-17T10:13:26.509Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28846051,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-28T13:02:32.985Z","status":"ssl_error","status_checked_at":"2026-01-28T13:02:04.945Z","response_time":57,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker","etcd","gokit","golang","kubernetes","microservices","opentracing","prometheus","vagrant"],"created_at":"2026-01-28T13:31:53.117Z","updated_at":"2026-01-28T13:31:53.182Z","avatar_url":"https://github.com/buptmiao.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Microservice-app\n\n### 一. 简介\n\n该项目是基于go语言搭建的微服务架构应用. 包含如下组件:   \n\n1. 服务注册中心 [etcd](https://github.com/coreos/etcd)  \n2. Api 网关  \n3. Feed 服务  \n4. Profile 服务  \n5. Topic 服务  \n6. 监控组件: prometheus + grafana  \n7. 跟踪组件: zipkin + elasticsearch\n\n其中Feed, Profile, Topic 启动时会向etcd注册服务, Apigateway 通过调用这三个服务的客户端 Watch 到相应服务的注册Key, 同时得到服务的地址. 当服务实例个数动态伸缩时, Apigateway 也会实时响应变化.\n\n结构如下:  \n\n![block](https://github.com/buptmiao/microservice-app/blob/master/pictures/block.png) \n\n### 二. 项目源码\n\n目录 | 介绍 \n--------|-----------------\napigateway  |  注册app所有endpoint.\nclient      |  所有访问微服务的客户端, 供apigateway调用. 提供服务发现,负载均衡,错误重试和故障降级等功能.\ncmd         |  各个服务的启动命令.\ndocker      |  构建各个服务的docker镜像.\nfeed        |  feed服务.\nmonitor     |  监控组件.\nprofile     |  profile服务.\nproto       |  服务间IPC方式采用grpc.\ntopic       |  topic服务.\ntracer      |  分布式跟踪.\nvagrant     |  虚拟化分布式环境, 采用传统方式部署应用.\n    \n### 三. 部署应用\n\n目前使用了两种应用部署方式:传统部署方式和容器化部署方式\n\n#### 1. 传统部署\n 如果你熟悉[vagrant](https://www.vagrantup.com/), vagrant目录下有具体部署细节. 参考[Vagrantfile](https://github.com/buptmiao/microservice-app/blob/master/vagrant/Vagrantfile) 和 [provision.sh](https://github.com/buptmiao/microservice-app/blob/master/vagrant/provision.sh)\n 总的来讲,项目使用vagrant虚拟化了5个节点, 节点0部署etcd, 节点1-4分别部署service-feed, service-profile, service-topic, apigateway.\n```ruby\n $nodes = 5\n Vagrant.configure(\"2\") do |config|\n     config.vm.box = \"centos/7\"\n     (0..($nodes - 1)).each do |i|\n         config.vm.define name=\"node-#{i}\", primary: (i == 0), autostart: (i == 0) do |node|\n             node.vm.hostname = name\n             node.vm.network \"private_network\", ip: \"192.168.50.#{10+i}\"\n             node.vm.provision \"shell\", path: \"provision.sh\", env: {\"LOCAL_IP\" =\u003e \"192.168.50.#{10+i}\", \"ETCD_ENDPOINT\" =\u003e \"http://192.168.50.10:2379\"}\n         end\n     end\n end\n```\n\n部署前请确保[vagrant-1.9.0](https://releases.hashicorp.com/vagrant/1.9.0/), 至于为什么是该版本, 个人认为该版本目前(2016-12-10)来看最稳定,bug最少.\n\n在vagrant目录下, 使用如下命令, 启动所有节点. 该命令第一次启动时会创建5台虚拟机node-0 ~ node-4. 并下载安装所需的可执行文件.\n```\n# 注意: 首次启动会比较慢, 具体时间取决于网络.\n$ vagrant up /node-./\n```\n启动后, 可以通过`vagrant ssh` + `node-*` 连接任何虚拟机. 例如,如果想查看apigateway是否运行, 可以执行如下命令:\n```\n$ vagrant ssh node-4\n$ ps -ef | grep apigateway\n$ exit\n```\n\n如果启动成功, 那么可以访问我们的服务了\n\n```\n$ curl -XPUT \"http://192.168.50.14:8080/api/feed/create_feed\" -d '{\"id\": 100, \"user_id\": 123, \"content\": \"hello world\"}'  // 发布feed1\n$ curl -XPUT \"http://192.168.50.14:8080/api/feed/create_feed\" -d '{\"id\": 101, \"user_id\": 123, \"content\": \"goodbye!\"}'     // 发布feed2\n$ curl -XGET \"http://192.168.50.14:8080/api/feed/get_feeds?user_id=123\u0026\u0026size=2\"                                           // 拉取feed列表\n```\n\n将会显示\n```\n{\n    \"feeds\": [\n        {\n            \"id\": 100,\n            \"user_id\": 123,\n            \"content\": \"hello world\"\n        },\n        {\n            \"id\": 101,\n            \"user_id\": 123,\n            \"content\": \"goodbye!\"\n        }\n    ]\n}\n```\n\n注意: 默认每一个微服务只启动一个实例, 如果想看多个微服务实例, 那么可以到某个节点上手动启动. 例如:\n```\n$ vagrant ssh node-2\n$ nohup feed -addr=$LOCAL_IP:8082 -etcd.addr=$ETCD_ENDPOINT 0\u003c\u0026- \u0026\u003e/dev/null \u0026  //nohup 忽略用户退出时的hup信号, 这样当退出ssh时feed进程不会受到影响. 实际上feed进程源码中实现了对某些信号的处理.\n$ exit\n```\n这样, 对于feed相关的请求,apigateway会把每一个请求通过round robin的方式均衡的打到两个feed实例上,实现进程内负载均衡. 同样需要注意: 原则上说, 微服务都应该是无状态的. 然而为了简单,该项目中的微服务实例都是采用内存存储. 所以在多实例环境下, 如果你发布了一条feed, 却没有拉取到, 那么多试几次即可.\n\n#### 2. 容器化部署\n\n如果你对docker熟悉的话, docker目录下提供了构建镜像的脚本 [build.sh](https://github.com/buptmiao/microservice-app/blob/master/docker/build.sh).\n```\n./build.sh\n```\n该脚本生成4个服务的docker镜像, 然后我们通过docker-compose命令启动容器.\n\n```\ndocker-compose up -d\n```\n\n启动成功后:\n```\n$ curl -XPUT \"http://localhost:8080/api/feed/create_feed\" -d '{\"id\": 100, \"user_id\": 123, \"content\": \"hello world\"}'  // 发布feed1\n$ curl -XPUT \"http://localhost:8080/api/feed/create_feed\" -d '{\"id\": 101, \"user_id\": 123, \"content\": \"goodbye!\"}'     // 发布feed2\n$ curl -XGET \"http://localhost:8080/api/feed/get_feeds?user_id=123\u0026\u0026size=2\"                                           // 拉取feed列表\n```\n\n### 四. 应用监控\n\n应用监控采用[prometheus](https://github.com/prometheus/prometheus) + [grafana](https://github.com/grafana/grafana) + [cadvisor](https://github.com/google/cadvisor) + [alertmanager](https://github.com/prometheus/alertmanager).\n\n#### 启动监视器\n\n启动监视器之前请先阅读[README](https://github.com/buptmiao/microservice-app/blob/master/monitor/README.md). \n\n如果是使用方式1部署的应用, 在monitor目录下, 可以通过如下配置target, 来监视app\n\n```\n- targets: ['localhost:9090','cadvisor:8080', '192.168.50.11:6062', '192.168.50.12:6063', '192.168.50.13:6064', '192.168.50.14:6060']\n```\n\n然后在monitor目录下\n```\n$ docker-compose up\n```\n\n这样监视器启动成功.\n\n如果采用方式2部署的应用, docker-compose文件已经配置好. 直接在monitor目录下:\n```\n$ docker-compose -f docker-compose.yml.2 up -d\n```\n\n两种方式启动成功后, 都可以通过访问: http://localhost:9090/graph 来查看metrics.\n\n#### 可视化\n\n可视化采用grafana, 它与prometheus结合的很好, 采用该方案可以很好的监控docker容器的状态\n\n打开浏览器 [http://localhost:3000](http://localhost:3000), 进入grafana, 添加数据源, Type选择Prometheus, Access选择direct模式, 填写prometheus的url: http://localhost:9090, 勾上默认. Save \u0026 test. 退出.\n\n添加dashboard, 导入monitor/grafana/docker_dashboard.json 即可看到下图:\n\n![docker_dashboard](https://github.com/buptmiao/microservice-app/blob/master/pictures/docker_dashboard.png) \n\n### 五. 跟踪\n\n分布式跟踪系统采用 [zipkin](https://github.com/openzipkin/zipkin) + elasticsearch后端, zipkin负责UI和span收集, es负责海量数据存储和索引. 在App中已经集成了zipkin的客户端代码, 只需要在程序执行时设置-zipkin.addr参数即可, 例如:\n\n```\ngo run cmd/feed/main.go -etcd.addr=http://localhost:2379 -zipkin.addr=http://localhost:9411/api/v1/spans\n```\n\ntracer目录下提供了一个docker-compose.yml文件, 它在docker/docker-compose.yml的基础上集成了zipkin和elasticsearch. 在该目录下:\n```\n$ docker-compose up -d\n```\n\n启动成功后可以通过curl访问:\n```\n$ curl -XPUT \"http://localhost:8080/api/feed/create_feed\" -d '{\"id\": 100, \"user_id\": 123, \"content\": \"hello world\"}'  // 发布feed1\n$ curl -XPUT \"http://localhost:8080/api/feed/create_feed\" -d '{\"id\": 101, \"user_id\": 123, \"content\": \"goodbye!\"}'     // 发布feed2\n$ curl -XGET \"http://localhost:8080/api/feed/get_feeds?user_id=123\u0026\u0026size=2\"                                           // 拉取feed列表\n```\n这时候跟踪系统已经有了3条数据.\n\n浏览器打开[http://localhost:9411](http://localhost:9411), 服务名选择http, 并选择合适的时间范围, 然后点击Find traces, 便可找到这3条traces.\n随便点一条进去可以看到如下图所示跟踪轨迹(由于该App功能简单,调用深度目前只有两层):\n \n![tracing](https://github.com/buptmiao/microservice-app/blob/master/pictures/tracing.png) \n\n### 六. Todo\n* 使用kubenetes部署整个应用\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbuptmiao%2Fmicroservice-app","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbuptmiao%2Fmicroservice-app","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbuptmiao%2Fmicroservice-app/lists"}