{"id":37016929,"url":"https://github.com/zzq0324/feature-flag","last_synced_at":"2026-01-14T01:56:11.532Z","repository":{"id":57716257,"uuid":"376807370","full_name":"zzq0324/feature-flag","owner":"zzq0324","description":null,"archived":false,"fork":false,"pushed_at":"2021-09-22T09:39:24.000Z","size":492,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-09T04:04:57.135Z","etag":null,"topics":["feature-flag"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zzq0324.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}},"created_at":"2021-06-14T12:00:37.000Z","updated_at":"2022-01-15T12:50:16.000Z","dependencies_parsed_at":"2022-08-25T09:21:43.998Z","dependency_job_id":null,"html_url":"https://github.com/zzq0324/feature-flag","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/zzq0324/feature-flag","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zzq0324%2Ffeature-flag","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zzq0324%2Ffeature-flag/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zzq0324%2Ffeature-flag/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zzq0324%2Ffeature-flag/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zzq0324","download_url":"https://codeload.github.com/zzq0324/feature-flag/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zzq0324%2Ffeature-flag/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28408692,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T00:40:43.272Z","status":"ssl_error","status_checked_at":"2026-01-14T00:40:42.636Z","response_time":56,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5: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":["feature-flag"],"created_at":"2026-01-14T01:56:10.797Z","updated_at":"2026-01-14T01:56:11.523Z","avatar_url":"https://github.com/zzq0324.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Feature Flag\n\n## 1、为什么需要Feature Flag\n\n\u003e Feature Flag(又名 Feature Toggle、Flip等)是一种允许控制线上功能开启或者关闭的方式，通常会采取配置文件的方式来控制。\n\n**引入Feature Flag有以下优势：**\n\n- 增强持续部署的信心；\n- A/B testing 支持；\n- 特性开放范围控制，有效验证线上新特性功能，针对特定人群发布功能尽早获得反馈，减少线上问题影响范围；\n- 可作为限流、降级之外有效的应急预案；\n- 能线上开启或者关闭,实现快速回滚。\n\n## 2、Feature Flag技术实现\n\n### 2.1 框架设计图\n\n![框架设计图](docs/images/Feature%20Flag框架设计.png)\n\n### 2.2 灰度算法\n\n详见[Feature Flag灰度算法](docs/algorithm.md)\n\n### 2.3 灰度判断逻辑\n\n![灰度判断逻辑](docs/images/灰度查询处理过程.png)\n\n## 3、使用说明\n\n对于接入方，需要完成Apollo、代码接入2个步骤才能最终用上Feature Flag。具体如下：\n\n### 3.1 Apollo配置\n\n一个完整的Feature Flag配置如下：\n```properties\n# 灰度开关描述\nflags.enable-open-search.desc=控制是否开启开放搜索\n# 灰度开始时间，留空默认不限制开始时间\nflags.enable-open-search.startTime=2021-06-12 01:02:03\n# 灰度结束时间，留空默认不限制开始时间\nflags.enable-open-search.endTime=\n# 灰度白名单，允许为空\nflags.enable-open-search.whiteList=u1,u2,u3\n# 灰度黑名单，允许为空\nflags.enable-open-search.blackList=\n# 灰度比例\nflags.enable-open-search.launchPercent=95\n```\n\n### 3.2 项目引入\n\n#### 3.2.1 `pom.xml`引入依赖\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003ecn.zzq0324\u003c/groupId\u003e\n    \u003cartifactId\u003efeature-flag\u003c/artifactId\u003e\n    \u003cversion\u003e1.0.2\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n#### 3.2.2 代码调用\n\n* **场景一：同个业务id严格控制每次执行结果一致**\n    ```java\n    FeatureFlagHelper.isFeatureOn(\"$flagName\", \"$bizId\");\n    ```\n\n* **场景二：控制流量整体趋势符合灰度比例，同个业务id执行结果不要求强一致**\n    ```java\n    FeatureFlagHelper.isFeatureOn(\"$flagName\");\n    ```\n\n## 4、命名规范和管理流程\n\n### 4.1 命名规范\n\nflag名称尽量以`enable-`开头，例如`enable-open-search`。\n\n### 4.2 Feature Flag声明周期\n\n![Feature Flag声明周期](docs/images/lifecycle.png)\n\n## 5、参考资料\n\n* [为什么Java String哈希乘数为3？](https://mp.weixin.qq.com/s/sCWQGU_OWiQkDUuSPXvw-w)\n* [FNV哈希算法](https://blog.csdn.net/hustfoxy/article/details/23687239)\n* [JavaFNV](https://github.com/Killeroid/JavaFNV)\n* [Fowler–Noll–Vo hash function](https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzzq0324%2Ffeature-flag","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzzq0324%2Ffeature-flag","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzzq0324%2Ffeature-flag/lists"}