草庐IT

分布式项目中,选型与依赖管理

知了一笑 2023-03-28 原文

JAR包:如果我依赖你,那劝你别依赖我。

一、技术视野

1、背景描述

在分布式系统搭建的初期,对于组件的选型是需要慎重考虑的,特别是对于同一个场景但是有多个不同组件可选项时,需要经过一定的调研再去确定最终选择,从而尽量避免后期业务发展引起核心组件的替换问题。

不同的技术选型,意味着不同的依赖包和版本,作为工程的基础,复杂的系统中管理庞大的依赖,需要具备体系化的思维。

2、开源体系

从个人习惯上来看,在核心的技术组件选型上,优先考虑从Spring和Apache两个生态中寻找,所以要对这两套开源体系下的组件有广泛的了解,以及相关配套的集成工具,在开发过程中有很多复杂的技术实现都是有对应的封装包来解决,更多的时候是不熟悉或没注意到;

再者就是很多热门的开源项目,这里理解为针对某个场景可以提供更好的解决方案,比如缓存或者任务调度等,在这个选择中可以优先关注大厂的开源组件,经过复杂业务的考验会相对成熟和稳定。

大部分情况下技术需求基于现有开源生态都是可以寻到相应的解决方案,所以定期关注开源组件的发布更新,对于开阔思路和视野有极大的帮助。这里从广泛的角度看开源体系,实际的项目中是有很多轻量级的工具包,可以简化代码和提升效率。

二、框架层面

1、JDK版本

对于核心框架的依赖,除了选型这个方面,还要考虑的就是版本问题,对于很多小厂来说更多的是处在一种"等待"的状态,等待开源市场给出更合理的选择。

就从JDK的选择来看,作为Java工程中最底层的依赖,很多项目都是从JDK5直接跳跃到JDK8的,多数开源组件的最低依赖也需要JDK8,从版本的发布上看也就算个中间版。

所以在核心依赖上优先考虑使用最多的版本,至于后续要升级到什么版本,稍微留心注意下就会知道。如果版本过旧会和大多数组件冲突,如果版本过新要适配突发的问题,从选择上看不算特别明智。

2、核心框架

核心框架依赖的选择,需要遵守一个体系的原则,例如在Java工程中必选的Spring体系,在微服务的架构设计中,对于服务注册发现,通信请求,网关路由等功能组件,都可以围绕SpringCloud的相关集成去做选择,这样可以有效减少技术带来的负担,并且具有活跃的社区和详细的文档支撑。

三、单工程分层

微服务的架构中,针对单服务的工程代码也会分包管理,不同分层的包管理特定性质的代码文件,除了各个服务依赖公共包core(常见命名)之外,通常至少划分bean、feign、serve三层:

  • core:各个服务依赖的基础包,封装技术层面的解决方法,或业务的复用功能;
  • bean:工程对象(入参出参)和常量管理,一般不包括数据表的映射对象;
  • feign:服务交互的接口层封装,工程间通信的核心依赖;
  • serve:服务中具体业务实现层,控制层与feign接口层对应;

这样分层分包管理工程,服务之间的依赖就会清晰许多,也极大的保证了代码的复用性,版本升级时弃用的代码标记为过期,同时指向新的代码路径,其他服务升级时再跟随升级,最终彻底剔除过时代码,以此避免业务发展导致代码工程的混乱。

四、中间件

中间件在服务中是必不可少的业务支撑,例如开发中最常用的几个:缓存管理、消息队列、任务调度等;

消息队列:可以通过模式封装,实现消息的统一总线管理,避免消息混乱;例如之前总结过的消息中间件改造方案:

缓存管理:每个服务都或多或少存在缓存需求,缓存机制也具有一定的共性;

任务调度:通常会将任务调度的组件集成在单个服务中,实现调度管理的基本能力,然后采用服务间通信机制(例如Feign接口),去触发待任务执行;

中间件并不仅仅是引入依赖然后各种API的调用,基于什么策略和设计模式去管理,会给工程带来不同的影响。

五、轻量工具

许多项目下都会有一个util分包,用来存放常用的工具代码文件,如果是在复杂的分布式项目中,通常打成独立的jar包,后来这些基础的工具类被汇聚到开源项目中,极大的降低维护成本,并且可以标准化的使用工具:

对于工具包中提供哪些核心能力,经常查阅相关文档即可,像一些:日期、字符串、集合、JSON、Http、文件流等常见功能,都会封装相应的处理方法。lombok插件可以高度简化Java对象中代码,以及对象的使用。

工具型的组件,更倾向于在开发过程中明确规定使用哪一个,尽量避免混搭使用,并且要熟悉工具包提供的各种能力,减少不必要的重复封装,对于类库中的常用方法也可以多阅读,被多数开发认可的代码,必然可以开阔自己的代码编写思路。

最后,很多技术栈或者开源组件的不断发展,都是为了可以更好的解决场景问题,这就需要开发人员定期关注技术的发展趋势,具备技术视野和洞察能力。

六、参考源码

应用仓库:
https://gitee.com/cicadasmile/butte-flyer-parent

组件封装:
https://gitee.com/cicadasmile/butte-frame-parent

有关分布式项目中,选型与依赖管理的更多相关文章

  1. ruby - i18n Assets 管理/翻译 UI - 2

    我正在使用i18n从头开始​​构建一个多语言网络应用程序,虽然我自己可以处理一大堆yml文件,但我说的语言(非常)有限,最终我想寻求外部帮助帮助。我想知道这里是否有人在使用UI插件/gem(与django上的django-rosetta不同)来处理多个翻译器,其中一些翻译器不愿意或无法处理存储库中的100多个文件,处理语言数据。谢谢&问候,安德拉斯(如果您已经在ruby​​onrails-talk上遇到了这个问题,我们深表歉意) 最佳答案 有一个rails3branchofthetolkgem在github上。您可以通过在Gemfi

  2. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  3. ruby-on-rails - 项目升级后 Pow 不会更改 ruby​​ 版本 - 2

    我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby​​版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby​​版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘

  4. ruby-on-rails - 新 Rails 项目 : 'bundle install' can't install rails in gemfile - 2

    我已经像这样安装了一个新的Rails项目:$railsnewsite它执行并到达:bundleinstall但是当它似乎尝试安装依赖项时我得到了这个错误Gem::Ext::BuildError:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcheckingforlibkern/OSAtomic.h...yescreatingMakefilemake"DESTDIR="cleanmake"DESTDIR="

  5. ruby-on-rails - 在 ruby​​ .gemspec 文件中,如何指定依赖项的多个版本? - 2

    我正在尝试修改当前依赖于定义为activeresource的gem:s.add_dependency"activeresource","~>3.0"为了让gem与Rails4一起工作,我需要扩展依赖关系以与activeresource的版本3或4一起工作。我不想简单地添加以下内容,因为它可能会在以后引起问题:s.add_dependency"activeresource",">=3.0"有没有办法指定可接受版本的列表?~>3.0还是~>4.0? 最佳答案 根据thedocumentation,如果你想要3到4之间的所有版本,你可以这

  6. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  7. ruby-on-rails - 获取 inf-ruby 以使用 ruby​​ 版本管理器 (rvm) - 2

    我安装了ruby​​版本管理器,并将RVM安装的ruby​​实现设置为默认值,这样'哪个ruby'显示'~/.rvm/ruby-1.8.6-p383/bin/ruby'但是当我在emacs中打开inf-ruby缓冲区时,它使用安装在/usr/bin中的ruby​​。有没有办法让emacs像shell一样尊重ruby​​的路径?谢谢! 最佳答案 我创建了一个emacs扩展来将rvm集成到emacs中。如果您有兴趣,可以在这里获取:http://github.com/senny/rvm.el

  8. Ruby 从大范围中获取第 n 个项目 - 2

    假设我有这个范围:("aaaaa".."zzzzz")如何在不事先/每次生成整个项目的情况下从范围中获取第N个项目? 最佳答案 一种快速简便的方法:("aaaaa".."zzzzz").first(42).last#==>"aaabp"如果出于某种原因你不得不一遍又一遍地这样做,或者如果你需要避免为前N个元素构建中间数组,你可以这样写:moduleEnumerabledefskip(n)returnto_enum:skip,nunlessblock_given?each_with_indexdo|item,index|yieldit

  9. ruby - 分布式事务和队列,ruby,erlang,scala - 2

    我有一个涉及多台机器、消息队列和事务的问题。因此,例如用户点击网页,点击将消息发送到另一台机器,该机器将付款添加到用户的帐户。每秒可能有数千次点击。事务的所有方面都应该是容错的。我以前从未遇到过这样的事情,但一些阅读表明这是一个众所周知的问题。所以我的问题。我假设安全的方法是使用两阶段提交,但协议(protocol)是阻塞的,所以我不会获得所需的性能,我是否正确?我通常写Ruby,但似乎Redis之类的数据库和Rescue、RabbitMQ等消息队列系统对我的帮助不大——即使我实现某种两阶段提交,如果Redis崩溃,数据也会丢失,因为它本质上只是内存。所有这些让我开始关注erlang和

  10. ruby-on-rails - 事件管理员日期过滤器日期格式自定义 - 2

    是否有简单的方法来更改默认ISO格式(yyyy-mm-dd)的ActiveAdmin日期过滤器显示格式? 最佳答案 您可以像这样为日期选择器提供额外的选项,而不是覆盖js:=f.input:my_date,as::datepicker,datepicker_options:{dateFormat:"mm/dd/yy"} 关于ruby-on-rails-事件管理员日期过滤器日期格式自定义,我们在StackOverflow上找到一个类似的问题: https://s

随机推荐