当前位置: 首页 > news >正文

那个网站做logo兼职网络运营策划

那个网站做logo兼职,网络运营策划,网页ui设计师培训,恩施网站开发概述 上两篇文章#xff0c;我们讲解了灰度组件的需求和设计的思路。不管之前讲的限流、幂等框架#xff0c;还是现在讲的灰度组件#xff0c;功能性需求都不复杂#xff0c;相反#xff0c;非功能性需求是开发的重点。 本章#xff0c;按照上篇文章的灰度组件的设计思…概述 上两篇文章我们讲解了灰度组件的需求和设计的思路。不管之前讲的限流、幂等框架还是现在讲的灰度组件功能性需求都不复杂相反非功能性需求是开发的重点。 本章按照上篇文章的灰度组件的设计思路讲解如何进行编码实现。不过本章对实现的讲解前前面两个实战项目有所不同。在前两个项目中我们都是手把手从最基础的 MVP 代码将其。然后讲解如何 review 代码发现问题、重构代码解决问题最终得到一份高质量的代码。考虑到前面两个项目的学习锻炼你应该对开发套路、思考路径已经很熟悉了所以本章就不从最基础的将其了而是重点讲解实现思路。 灰度组件功能需求整理 针对上连篇文章的开发需求和设计思路我们还是按照老套路从中剥离出 V1 版本要实现的内容。为了方便讲解我把灰度组件的开发需求和设计思路重新整理罗列了一下放到了这里。 1.灰度规则的格式和存储方式 支持不同格式JSON、YAML、XML 等、不同存储方式本地配置我呢间、Redis、Zookeeper、或者自研配置中心的灰度规则配置方式。实际上这一点和之前的限流框架中限流规则的格式和存储方式完全一致代码实现也是相同的。所以这个就不重复了你可以回头去看《限流框架实现》章节内容。 2.灰度组件的语法格式 我们支持三种灰度规则语法格式具体值比如 893、区间值比如 1020-1120、比例值比如 %30。此外对于更加复杂的灰度规则比如只对 30 天内购买过某某商品并且退款次数少于 10 次的用户进行更改我们通过编程的方式来实现。 3.灰度规则的内存组织方式 类似于限流框架中的限流规则我们需要把灰度规则组织成支持快速查询的数据结构能够快速判定某个灰度对象darkTarget比如用户 ID是否落在灰度规则设定的范围内。 4.灰度规则热更新 修改了灰度规则之后我们不希望重新部署和重启系统新的灰度规则就能生效所以我们需要支持灰度规则热更新。 在 V1 版本中对于第一点灰度规则的合适和存储方式我们只支持 YAML 格式本地文件的配置存储方式。对于剩下的三点我们都要进行实现。考虑到 V1 版本要实现的内容比较多我们分两步来实现代码第一步先讲大的流程、框架搭建好第二步再进一步添加、丰富、优化功能。 实现灰度组件基本功能 // 目录结构 com.example.darklaunch--DarkLaunch (框架的最顶层入口类)--DarkFeature (每个feature的灰度规则)--DarkRule (灰度规则)--DarkRuleConfig (用来映射配置到内存中)// Demo示例 public class Demo {public static void main(String[] args) {DarkLaunch darkLaunch new DarkLaunch();DarkFeature darkFeature darkLaunch.getDarkFeature(call_newapi_getUserById);System.out.println(darkFeature.enabled());System.out.println(darkFeature.dark(893));} }// 灰度规则配置(dark-rule.yaml)放在classpath路径下 features - key: call_newapi_getUserByIdenabled: truerule: {893,342,1020-1120,%30} - key: call_newapi_registerUserenabled: truerule: {1391198723, %10} - key: newlog_loanenabled: truerule: {0-1000}从 Demo 代码中可以看出对于业务系统来说灰度组件的两个直接使用的类是 DarkLaunch 和 DarkFeature。 我们先来看 DarkLaunch 类。这个类是灰度组件最顶层入口类。它用来组装其他类对象串联整个操作流程提供外部调用的接口。 DarkLaunch 类先读取灰度规则配置文件映射为内存中的 Java 对象DarkRuleConfig然后再将这个中间结构构建成一个支持快速查询的数据结构DarkRule。此外它还负责定期更新灰度规则也就是前面提到的灰度热更新。 为了避免更新规则和查询规则并发冲突在更新灰度时我们并非直接操作老的 DarkRule而是先创建一个新的 DarkRule然后等新的 DarkRule 都构建好之后再 “瞬间” 赋值给老的 DarkRule。 public class DarkLaunch {private static final Logger log LoggerFactory.getLogger(DarkLaunch.class);private static final int DEFAULT_RULE_UPDATE_TIME_INTERVAL 60; // in secondsprivate DarkRule rule;private ScheduledExecutorService executor;public DarkLaunch(int ruleUpdateTimeInterval) {loadRule();this.executor Executors.newSingleThreadScheduledExecutor();this.executor.scheduleAtFixedRate(new Runnable() {Overridepublic void run() {loadRule();}}, ruleUpdateTimeInterval, ruleUpdateTimeInterval, TimeUnit.SECONDS);}public DarkLaunch() {this(DEFAULT_RULE_UPDATE_TIME_INTERVAL);}private void loadRule() {// 将灰度规则配置文件dark-rule.yaml中的内容读取到DarkRuleConfig中InputStream in null;DarkRuleConfig ruleConfig null;try {in this.getClass().getResourceAsStream(dark-rule.yaml);if (in ! null) {Yaml yaml new Yaml();ruleConfig yaml.loadAs(in, DarkRuleConfig.class);}} finally {if (in ! null) {try {in.close();} catch (IOException e) {log.error(close file error:, e);}}}if (ruleConfig null) {throw new RuntimeException(can not load dark rule.);}// 更新规则并非直接在this.rule上进行// 而是通过创建一个新的 DarkRule然后赋值给this.rule// 来避免更新规则和规则查询的并发冲突问题DarkRule darkRule new DarkRule(ruleConfig);this.rule darkRule;}public DarkFeature getDarkFeature(String featureKey) {return this.rule.getDarkFeature(featureKey);} }**再来看下 DarkRuleConfig 类。**这个类功能非常简单只是用来将灰度规则映射到内存中。 public class DarkRuleConfig {private ListDarkFeatureConfig features;public ListDarkFeatureConfig getFeatures() {return features;}public void setFeatures(ListDarkFeatureConfig features) {this.features features;}public static class DarkFeatureConfig {private String key;private boolean enable;private String rule;public String getKey() {return key;}public void setKey(String key) {this.key key;}public boolean isEnable() {return enable;}public void setEnable(boolean enable) {this.enable enable;}public String getRule() {return rule;}public void setRule(String rule) {this.rule rule;}} } 从代码中我们可以看出来DarkRuleConfig 类嵌套了一个内部类 DarkFeatureConfig。这两个类跟配置文件中的两层嵌套结构完全对应 。 # 对应DarkRuleConfig features - key: call_newapi_getUserById # 对应DarkFeatureConfigenabled: truerule: {893,342,1020-1120,%30} - key: call_newapi_registerUser # 对应DarkFeatureConfigenabled: truerule: {1391198723, %10} - key: newlog_loan # 对应DarkFeatureConfigenabled: truerule: {0-1000}再来看下 DarkRule。DarkRule 包含所有要灰度的业务功能的灰度规则。它用来支持根据业务功能标识feature key快速查询灰度规则DarkFeture。 public class DarkRule {private MapString, DarkFeature darkFeatures new HashMap();public DarkRule(DarkRuleConfig darkRuleConfig) {ListDarkRuleConfig.DarkFeatureConfig darkRuleConfigFeatures darkRuleConfig.getFeatures();for (int i 0; i darkRuleConfigFeatures.size(); i) {DarkRuleConfig.DarkFeatureConfig darkFeatureConfig darkRuleConfigFeatures.get(i);darkFeatures.put(darkFeatureConfig.getKey(), new DarkFeature(darkFeatureConfig));}}public DarkFeature getDarkFeature(String featureKey) {return this.darkFeatures.get(featureKey);} }最后我们来看下 DarkFeature 类。 DarkFeature 类标识每个要灰度的业务功能的灰度规则。DarkFeature 将配置文件中的灰度规则解析成一定的结构比如 RangeSet方便快速判定某个灰度对象是否落在灰度规则范围内。 public class DarkFeature {private String key;private boolean enabled;private int percentage;private RangeSetLong rangeSet TreeRangeSet.create();public DarkFeature(DarkRuleConfig.DarkFeatureConfig darkFeatureConfig) {this.key darkFeatureConfig.getKey();this.enabled darkFeatureConfig.isEnable();String darkRule darkFeatureConfig.getRule().trim();parseDarkRule(darkRule);}VisibleForTestingprotected void parseDarkRule(String darkRule) {if (!darkRule.startsWith({) !darkRule.endsWith(})) {throw new RuntimeException(failed to parse dark rule: darkRule);}String[] rules darkRule.substring(1, darkRule.length() - 1).split(,);this.rangeSet.clear();this.percentage 0;for (String rule : rules) {rule rule.trim();if (StringUtils.isEmpty(rule)) {continue;}if (rule.startsWith(%)) {this.percentage Integer.parseInt(rule.substring(1));} else if (rule.contains(-)) {String[] parts rule.split(-);if (parts.length ! 2) {throw new RuntimeException(failed to parse dark rule: darkRule);}long start Long.parseLong(parts[0]);long end Long.parseLong(parts[1]);if (start end) {throw new RuntimeException(failed to parse dark rule: darkRule);}this.rangeSet.add(Range.closed(start, end));} else {long val Long.parseLong(rule);this.rangeSet.add(Range.closed(val, val));}}}public boolean isEnabled() {return enabled;}public boolean dark(long darkTarget) {boolean selected this.rangeSet.contains(darkTarget);if (selected) {return true;}long reminder darkTarget % 100;if (reminder 0 reminder this.percentage) {return true;}return false;}public boolean dark(String darkTarget) {long target Long.parseLong(darkTarget);return dark(target);} } 添加、优化灰度组件 在第一步中我们完成了灰度组件的基本功能。在第二步中我们再实现基于编程的灰度规则配置方式用来支持更复杂、更加灵活的灰度规则。 我们需要对第一步实现的代码进行一些改造。改造之后的目录结构如下所示。其中DarkFeature、DarkRuleConfig 的代码基本不变 新增了 IDarkFeature 接口DarkLaunch 、DarkRule 的代码有所改动用来支持编程实现灰度规则。 // 第一步的代码目录结构 com.example.darklaunch--DarkLaunch (框架的最顶层入口类)--DarkFeature (每个feature的灰度规则)--DarkRule (灰度规则)--DarkRuleConfig (用来映射配置到内存中)// 第二步的代码目录结构 com.example.darklaunch--DarkLaunch (框架的最顶层入口类代码有所改动)--IDarkFeature (抽象接口)--DarkFeature (实现IDarkFeature接口基于配置文件的灰度规则代码不变)--DarkRule (灰度规则代码有改动)--DarkRuleConfig (用来映射配置到内存中代码不变)我们先来看下 IDarkFeature 接口它用来抽象从配置文件中得到的灰度规则以及编程实现的灰度规则。具体代码如下所示 public interface IDarkFeature {boolean isEnabled();boolean dark(long darkTarget);boolean dark(String darkTarget); }基于这个抽象接口业务系统可以自己编程实现复杂的灰度规则然后添加到 DarkRule 中。为了避免配置文件中的灰度规则热更新时覆盖编程实现的灰度规则在 DarkRule 中我们对从配置文件中加载的灰度规则和编程实现的灰度规则分开存储。按照这个设计思路我们对 DarkRule 类进行重构。重构之后的代码如下所示 public class DarkRule {// 从配置文件中加载的灰度规则private MapString, IDarkFeature darkFeatures new HashMap();// 编程实现的灰度规则private MapString, IDarkFeature programmedDarkFeatures new ConcurrentHashMap();public void addProgrammingDarkFeature(String featureKey, IDarkFeature darkFeature) {programmedDarkFeatures.put(featureKey, darkFeature);}public void setDarkRuleFeatures(MapString, IDarkFeature newDarkFeatures) {this.darkFeatures newDarkFeatures;}public IDarkFeature getDarkFeature(String featureKey) {IDarkFeature darkFeature programmedDarkFeatures.get(featureKey);if (darkFeature ! null) {return darkFeature;}return this.darkFeatures.get(featureKey);} }因为 DarkRule 代码有所修改对应地 DarkLaunch 的代码也需要做少许改动主要有一处修改和一处新增代码具体如下所示。 public class DarkLaunch {private static final Logger log LoggerFactory.getLogger(DarkLaunch.class);private static final int DEFAULT_RULE_UPDATE_TIME_INTERVAL 60; // in secondsprivate DarkRule rule;private ScheduledExecutorService executor;public DarkLaunch(int ruleUpdateTimeInterval) {loadRule();this.executor Executors.newSingleThreadScheduledExecutor();this.executor.scheduleAtFixedRate(new Runnable() {Overridepublic void run() {loadRule();}}, ruleUpdateTimeInterval, ruleUpdateTimeInterval, TimeUnit.SECONDS);}public DarkLaunch() {this(DEFAULT_RULE_UPDATE_TIME_INTERVAL);}private void loadRule() {// 将灰度规则配置文件dark-rule.yaml中的内容读取到DarkRuleConfig中InputStream in null;DarkRuleConfig ruleConfig null;try {in this.getClass().getResourceAsStream(dark-rule.yaml);if (in ! null) {Yaml yaml new Yaml();ruleConfig yaml.loadAs(in, DarkRuleConfig.class);}} finally {if (in ! null) {try {in.close();} catch (IOException e) {log.error(close file error:, e);}}}if (ruleConfig null) {throw new RuntimeException(can not load dark rule.);}// 修改单独更新从配置文件中得到的灰度规则MapString, IDarkFeature darkFeatures new HashMap();ListDarkRuleConfig.DarkFeatureConfig darkFeatureConfigs ruleConfig.getFeatures();for (DarkRuleConfig.DarkFeatureConfig darkFeatureConfig : darkFeatureConfigs) {darkFeatures.put(darkFeatureConfig.getKey(), new DarkFeature(darkFeatureConfig));}this.rule.setDarkRuleFeatures(darkFeatures);}// 新增添加编程实现的灰度规则的接口public void addProgrammingDarkFeature(String featureKey, IDarkFeature darkFeature) {this.rule.addProgrammingDarkFeature(featureKey, darkFeature);}public IDarkFeature getDarkFeature(String featureKey) {return this.rule.getDarkFeature(featureKey);} }灰度组件的代码实现完了。我们在通过一个 Demo 看下目前实现的灰度组件该如何使用。结合着 Demo再去理解上面的代码会更容易些。 // 灰度规则配置(dark-rule.yaml), 放到classpath路径下 features - key: call_newapi_getUserByIdenabled: truerule: {893,342,1020-1120,%30} - key: call_newapi_registerUserenabled: truerule: {1391198723, %10} - key: newlog_loanenabled: truerule: {0-1000}// 编程实现的灰度规则 public class UserPromotionDarkRule implements IDarkFeature {Overridepublic boolean isEnabled() {return true;}Overridepublic boolean dark(long darkTarget) {// 灰度规则自己想怎么写就怎么写return false;}Overridepublic boolean dark(String darkTarget) {// 灰度规则自己想怎么写就怎么写return false;} }// demo public class Demo {public static void main(String[] args) {DarkLaunch darkLaunch new DarkLaunch(); // 默认加载classpath下的dark-rule.yaml文件中的灰度规则darkLaunch.addProgrammingDarkFeature(user_promotion, new UserPromotionDarkRule());IDarkFeature darkFeature darkLaunch.getDarkFeature(user_promotion);System.out.println(darkFeature.isEnabled());System.out.println(darkFeature.dark(833));} }总结 到本章为止项目实战环节就彻底结束了。在这一部分中我们通过限流、幂等、灰度这三个实战项目带你从需求分析、系统设计、代码实现三个环节学习了如何进行功能性、非功能性需求分析如何通过合理的设计完成功能性需求满足非功能性需求以及如何编写高质量的代码实现。 实际上项目本身的分析、设计、实现并不重要不必对细节过于纠结。希望通过这三个例子分享思考思路、开发套路让你借鉴并举一反三地应用到你的项目开发中。这才是最有价值的才是你学习的重点。
http://www.dnsts.com.cn/news/101004.html

相关文章:

  • 嘉兴网站制作网站建设自助设计网站
  • 一个网站开发的流程图wordpress平铺图片
  • 建设部网站危房鉴定标准规定p2p贷款网站开发
  • jsp商务网站开发推广发帖网站
  • 如何删除自己建的网站公司注册资金实缴和认缴的区别
  • 高权重网站出售深圳几个区
  • 网站备案流程多少钱90设计网官网登录
  • 济宁网站定制公司wordpress安装脚本打不开
  • 达州 网站建设福州网站建设哪家好
  • 做网站用虚拟主机好不好广州网站建设360网站优化
  • 网站怎样做权重自己做的网站在浏览器上显示不安全吗
  • 网站建设与运行电视剧排行榜
  • 宁波网站制作怎样网页设计与制作教程杨选辉
  • 客户端 网站开发 手机软件开发网站系统改教程
  • 哈尔滨大型网站制作百度平台交易
  • 太原城市建设招标网站响应式网站建设联雅
  • 学做饼干的网站深圳装修公司电话号码大全
  • 生道网站建设平台广州巨腾建网站公司
  • 网站做造价设计一个电子商务网站
  • 苏州建设局网站wordpress表单上传多个文件
  • 各大行业网站网络设计工资一般多少
  • 网站开发杭州看房子建设进度的网站
  • 4s店网站建设网页设计师的发展
  • 响应式模板网站建设佛山企业网站建设特色
  • 番禺做网站公司哪家好wordpress导航栏链接没有生成
  • 网站建设用什么代码做网站搞活动
  • 中企动力邮箱官方网站二手车网站设计
  • 网站设计制作开发石家庄工信部网站备案
  • 网站ip需要备案专门做任务的网站吗
  • 中堂镇仿做网站郑州门户网站建设