これらのピットを避けるために---分散開発を実践的なプロジェクトを開発する春ブーツマイクロ電気サービスプロバイダー

今日七話すに入った、全体がマイクロサービスアーキテクチャ作業が大幅に完了している設定します。これまでのところ、実際に技術を使用しているものは何な機能を実現するには?さんがおさらいしてみましょう。

テクノロジーを使用: SpringBoot、ダボ、飼育係、Redisの、カフカが住んでいました

機能の実現:

サブ環境・デプロイメント構成やポートサービスの統一構成を実現するために1、Mavenの親子プロジェクト、

図2に示すように、統合アクセスダボ、サービス層、プロバイダ(4つ)と消費者(A)の構成と、サービスコール、マイクロランディングサービス実装のためのサブモジュール。

3、Mavenのサブモジュールプロジェクト(インターフェースとサービス層)統一構成管理の実装のバージョン番号。

4、Redisのアクセス、シングルサインオンと分散キャッシュを実装しています。

5、セキュリティインタフェース、トークン、署名アルゴリズムと塩を振りかける、署名、および傍受トークン検証プロセスをフィルタリングします。

6、グローバル例外ハンドラ、AOPのログ印刷、抗SQLインジェクション遮断処理の実装。

乾燥品のフルこれらは、私は私が記事の最近のシリーズではまだ満足して知りませんか?次に、私は中に深く続け、ゆっくりとそれを支える技術とマイクロ電気事業のサービスを実現するために、真実を探求して説明します。

次のように現在のプロジェクト・モジュールは、次のとおりです。

これまでのところ、唯一の深い徐々に後者で、実証プロジェクトを戦うために4マイクロサービス(プロバイダ)を達成し、マイクロサービスが増加していきます。今日、私は踏ま分散自分のピットでそれらのプロジェクトについてお話したいと思います。

1、エンティティのシリアル化の問題

あなたは小さなパートナーの開発を分散しなかった場合は、エンティティがシリアライズされていないプロジェクト場合は、注意を払うようにそこに持っている必要があり、それは消費者がスローされます受信サービスプロバイダのエンティティに戻ったときに、リモートプロシージャコールを達成することができない原因になります例外。

なぜそれをシリアル化しなければなりませんか?いくつかは、私は、エンティティが実行して良いことではないシリアライズされていない、プロジェクトをしなければならなかったことを言うかもしれません。プロジェクト全体あなたの前に内部JVMで:実行するには、Webコンテナ内のすべてのコードの前に、あなたのプロジェクトは、それが言うことだからです。

但分布式项目就不一样了,提供者和消费者是在不同的web容器里运行(不同的JVM)。消费者在进行远程方法调用时,实际就是消费者的jvm在调用提供者jvm里的对象,但这个对象在消费者的jvm里并不存在,那要获取就得用Java对象序列化来解决。简而言之:序列化的作用就是为了不同jvm之间共享实例对象的一种解决方案

2,分布式环境生成编号问题

这是我在项目中真真实实跳过的坑,根据之前多年项目的开发经验,一般编号(客户,商品、订单等编号)的生成规则基本都是借助于数据库的自增id实现,看似本来通用的解决方案,在分布式项目中,竟然是给自己埋坑。

之前的编号实现方式:在添加数据方法的Service实现里,先查询获得数据库最大ID对应的编号,然后给这个编号+1生成新编号作为当前新增数据的编号插入数据库。开始看着很完美,但后来突然有人反映编号重复,这就奇怪了?加班趴着debug代码,但就是找不出来问题的原因。面对这种突如其来的问题完全不知所措,不得不求助网络,各种搜索后才明白,是提供者集群惹的祸。

原因分析:当两个及以上并发请求同时进入集群中的不同提供者时,一个提供者的Service实现在生成编号并插入数据之前,另一个提供者的Service也查询了数据库并获取了跟前一个提供者获取相同的最大编号。导致两台服务最终生成的编号相同。那可能也有人说了,你先插入数据,然后根据插入数据生成的自增id再去生成编号更新数据库不就解决了。但你有没想过,更新数据库操作需要锁表,在高并发请求的情况下,这会造成很大的性能瓶颈。

目前流行的解决方案:雪花算法,是完全基于代码实现,不依赖数据库。

上图只是部分代码,我们看到这个工具类实现了单例模式,生成的编号是:时间(到毫秒)+ ip(后面取了4位) +  自增序列。

我来演示下效果吧,先写个main方法实例化工具类,并写for循环生成编号

我红框圈出来的,是在同一时间,虽然时间和四位ip相同,但后三位的自增序列值一直在递增。那如果服务端做集群呢,是不是编号又会重复?就算在同一时间的高并发请求,几个服务终端可能会生成时间相同、后三位序列号相同的编号,但是,不同终端通过ip最后获取的四位值肯定不同。所以不可能有重复出现。

3,日志统一打印问题

分布式环境中,如果每个服务的日志分散到各自服务所在机器上,那么以后如果线上出现异常或日志收集及分析检查时,会让你痛苦不已,集群和服务规模小还好,特别是在负载均衡后的多个服务实例,你无法确定某个请求被谁接收了,所以只能翻看每个实例的日志。

处理方案:Service业务实现层不要捕获异常,直接通过throws全部往外抛。

然后在接口层在做相应的统一处理,比如Aop里打印,或使用日志框架(如:ELK)统一收集等。这样如果你的服务层做了集群,线上报错你也不用纠结去哪个服务器看服务提供者的日志,你只要到对应接口层服务查看输出的日志或统一收集的地方去查看。

获取项目源代码,请扫码关注公众号,并发送Springboot获取。

 

おすすめ

転載: www.cnblogs.com/lyn20141231/p/11210342.html