GloryAdmin は、springboot2.1.9.RELEASE および vue-admin-template に基づくバックグラウンド フレームワークです。
GloryAdmin はロールベースの権限管理を使用します。ロールツリーは「システム管理者」をルートノードとするツリーであり、権限ツリーは複数のサブ権限ツリーから構成されます。 「システム管理者」はすべての権限を持ちます。システム管理者以外の役割は、現在の役割と直下の役割の情報を表示できますが、直下の役割の情報の追加、削除、変更のみが可能です(直下の役割:A は直属の役割です) B の従属ノードである場合、A は B の子ノードでなければなりません)。
グローリー管理者
プロジェクト | テクノロジー |
---|---|
バックエンドプロジェクト | スプリングブーツ |
フロントエンドプロジェクト | 要素 UI と Vue.js |
データベース | MySQL |
キャッシュ | レディス |
このプロジェクトは mysql データベースを使用します。データベース スクリプトを使用して 2 つのデータベースmulti_module_db multi_module_db_01を作成できます。
バックグラウンドで起動し、ポート 28081 を使用します
フロントエンドを起動し、ポート 9523 を使用します。
ブラウザを開いて http://localhost:9523 admin a123456 にアクセスします。
シャーディングまたはシャーディングの本質は、ムーアの法則の破綻です。単一のデータ ノードにデータを一元的に保存するソリューションは、パフォーマンス、可用性、運用および保守コストの点で、インターネットの大規模なデータ シナリオを満たすことが困難でした。
単一のデータベースでは既存のビジネスをサポートできないため、サブデータベースやテーブルが登場し、データの保存には複数のデータベースが使用されます。サブデータベースとサブテーブルを簡単に理解すると、バスケットの内容は制限されており、これが検索効率と容量に影響します。バスケットの内容は N 個の部分に分割され、異なるバスケットに配置されます。これにより、容量の制約がなくなり、クエリの効率が向上します。
次に、中国で人気のある分散データベースには、Tencent の TDSQL、Alibaba の OceanBase、PolarDB、Huawei の GaussDB などが含まれます。基本的に、それらは独立して開発されており、強力な一貫性と高可用性、グローバル展開アーキテクチャ、分散型無制限の水平拡張、高性能、数千億のレコード、および数百 TB のデータに対する行間およびテーブル間のトランザクションを備えています (たとえば、祖国) 。分散データベースは、データベース シャーディングとテーブル シャーディングの戦略を隠し、データをデータベースとテーブルにインテリジェントにシャーディングし、データベースを操作するのと同じように使用します。
メモリ操作とディスク操作はまったく同じ桁ではないため、大規模なプロジェクトでは、ディスク データをメモリにキャッシュするために、ディスク タイプ データベース用のメモリ タイプのバッファ層が必要です。データ キャッシュ レイヤーは、サイト アクセスを高速化するためにデータ レイヤー全体のデータをキャッシュするために使用されます。このプロジェクトでは、 AOP テクノロジーとRedis インメモリ データベースをデータ キャッシュ レイヤーとして使用します。詳細については、コード com/spring/common/aop/CacheDaoAspect.java を確認してください。
このプロジェクトでは、シャーディング JDBC を使用してデータベースとデータベースのテーブルを処理します。ビジネス シナリオに応じてデータを自分で分割します。
通常、プロジェクトにはデータベースが 1 つだけあり、中国ではデータベース接続プールとして Alibaba Cloud の druid がより頻繁に使用されます。このプロジェクトでは、mysql、druid、シャーディング JDBC を使用します。データ シャーディングの原理は、プログラム内で複数のデータベース接続プールを維持することであり、各データベース接続プールはデータベースに対応します。シャード データベースとシャード テーブルは、XA プロトコルに基づいた 2 フェーズ トランザクション処理を使用します。設定パスcom.spring.common.config.shardingJDBC
垂直分割: ビジネス分割の方法は垂直シャーディングと呼ばれ、垂直分割とも呼ばれます。ビジネスに応じてテーブルを異なるデータベースに分散することで、異なるデータベースへの負担を分散します。
水平分割: ビジネス ロジックの分類を考慮せず、特定のテーブルの特定のフィールド (または複数のフィールド) を通じて、特定のルールに従ってデータを複数のライブラリまたはテーブルに分散します。ここでのルールと関連するアルゴリズムは、シャーディング アルゴリズムと呼ばれます。
(以下の内容は shardingJDBC ドキュメントから抜粋したものです)
PreciseShardingAlgorithm に対応し、単一のキーをシャーディング キーとして使用して=
およびIN
シャーディングのシナリオを処理するために使用されます。 StandardShardingStrategy と一緒に使用する必要があります。
RangeShardingAlgorithm に対応します。これは、単一のキーをシャーディング キーとして使用し、 BETWEEN AND
、 >
、 <
、 >=
、および<=
使用してシャーディング シナリオを処理するために使用されます。 StandardShardingStrategy と一緒に使用する必要があります。
ComplexKeysShardingAlgorithm に対応します。これは、複数のキーがシャーディングのシャーディング キーとして使用されるシナリオを処理するために使用されます。複数のシャーディング キーを含むロジックは複雑であるため、アプリケーション開発者はその複雑さに対処する必要があります。 ComplexShardingStrategy と一緒に使用する必要があります。
HintShardingAlgorithm に対応し、 Hint
行シャーディングが使用されるシナリオを処理するために使用されます。 HintShardingStrategy と一緒に使用する必要があります。
ユーザーはログインしてトークンを取得し、ローカルに保存します (adminLogin)
ユーザーはトークンを送信してユーザー情報と権限情報を取得し、ストアに保存します。 F5 を押すとストアが失われるため、フロントエンドリクエストにインターセプターを追加します。ユーザー情報と権限情報がない場合は、ユーザー情報と権限を再取得します (getAdminInfo)。
ここで返されるのは、ロールではなくユーザーのすべての権限です。ユーザーはフロントエンド ルートを動的に生成します。
asyncRoutes は動的に生成された権限であり、ユーザーの権限がルートの権限に対応する場合、それが表示されます。
共通: データ操作、データ キャッシュ、トランザクション操作
管理者はコントローラーとしてのみ機能し、ユーザー要求とバックエンド ビジネス間の転送を処理するために使用されます。 (なぜこのように設計されているのでしょうか?) 一部のミドルウェア システムではリクエストの転送に RPC フレームワークを使用する必要があるため、また、一部の機密システムでは springMVC の使用を軽視し、リクエスト層を独自に開発するために vertx を選択するためです。
Maven 継承を使用してプロジェクトの依存関係を管理します。モジュールでは、依存関係はdependencyManagementを通じて導入され、サブプロジェクトはモジュールを継承するため、依存関係を導入するときにバージョンを指定する必要はありません。
グローバルログ処理
ユーザー操作ログにはアノテーション方式を採用しています。このメソッドで操作ログを記録する必要がある場合は、メソッド名の上に **@OperateLog** アノテーションを追加するだけです。
@ OperateLog
@ ApiOperation ( value = "登出" , notes = "登出" )
@ GetMapping ( Route . Admin . adminLogout )
public ResponseDate adminLogout ( HttpServletRequest httpServletRequest ) {
AdminInfoDTO adminInfoDTO = AdminTool . getAdminUser ( httpServletRequest );
AdminUser adminUser = adminUserMapper . selectByPrimaryKey ( adminInfoDTO . getAdminUk ());
adminUser . setNowToken ( "log-out" );
int result = adminUserService . updateAdminToken ( adminUser );
return ResponseDate . builder ()
. success ( result == 1 )
. build ();
}