JoyLau's Blog

JoyLau 的技术学习与思考

解决

Dockerfile

1
2
3
4
5
FROM centos:7
# 解决镜像中文乱码的问题
RUN yum install -y glibc-common kde-l10n-Chinese
RUN localedef -c -f UTF-8 -i zh_CN zh_CN.utf8
ENV LC_ALL zh_CN.UTF-8

错误信息

macOS 的问题报告

系统登录后报错信息如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
panic(cpu 0 caller 0xffffff7f83e24231): nvme: "Fatal error occurred. CSTS=0x1 US[1]=0x0 US[0]=0xa6 VID=0x144d DID=0xa808
. FW Revision=EXA7301Q\n"@/AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/IONVMeFamily/IONVMeFamily-470.100.17/IONVMeController.cpp:5320
Backtrace (CPU 0), Frame : Return Address
0xffffff8e0693b9e0 : 0xffffff800031868d mach_kernel : _handle_debugger_trap + 0x49d
0xffffff8e0693ba30 : 0xffffff8000452ab5 mach_kernel : _kdp_i386_trap + 0x155
0xffffff8e0693ba70 : 0xffffff800044463e mach_kernel : _kernel_trap + 0x4ee
0xffffff8e0693bac0 : 0xffffff80002bea40 mach_kernel : _return_from_trap + 0xe0
0xffffff8e0693bae0 : 0xffffff8000317d57 mach_kernel : _DebuggerTrapWithState + 0x17
0xffffff8e0693bbe0 : 0xffffff8000318147 mach_kernel : _panic_trap_to_debugger + 0x227
0xffffff8e0693bc30 : 0xffffff8000abf2bc mach_kernel : _panic + 0x54
0xffffff8e0693bca0 : 0xffffff7f83e24231 com.apple.iokit.IONVMeFamily : __ZN16IONVMeController8PolledIOEhP18IOMemoryDescriptorjyy18IOPolledCompletionjPKhm.cold.1
0xffffff8e0693bcc0 : 0xffffff7f83e0f362 com.apple.iokit.IONVMeFamily : __ZN16IONVMeController18RequestAsyncEventsEj
0xffffff8e0693be20 : 0xffffff8000a2fb29 mach_kernel : __ZN18IOTimerEventSource15timeoutSignaledEPvS0_ + 0x89
0xffffff8e0693be90 : 0xffffff8000a2fa49 mach_kernel : __ZN18IOTimerEventSource17timeoutAndReleaseEPvS0_ + 0x99
0xffffff8e0693bec0 : 0xffffff800035a645 mach_kernel : _thread_call_delayed_timer + 0xec5
0xffffff8e0693bf40 : 0xffffff800035a171 mach_kernel : _thread_call_delayed_timer + 0x9f1
0xffffff8e0693bfa0 : 0xffffff80002be13e mach_kernel : _call_continuation + 0x2e
Kernel Extensions in backtrace:
com.apple.iokit.IONVMeFamily(2.1)[2D554F70-092B-3B6B-B2AD-5C09EDB5B4F8]@0xffffff7f83e01000->0xffffff7f83e43fff
dependency: com.apple.driver.AppleMobileFileIntegrity(1.0.5)[4159DFFE-7746-3327-9752-C161DC295828]@0xffffff7f813a4000
dependency: com.apple.iokit.IOPCIFamily(2.9)[2F37AE58-E6B9-3B18-9092-3B80D34C334B]@0xffffff7f80d31000
dependency: com.apple.driver.AppleEFINVRAM(2.1)[10E46031-889C-3FB7-8B4B-0DECAB5AE325]@0xffffff7f81628000
dependency: com.apple.iokit.IOStorageFamily(2.1)[CB3CB8CA-881A-37F3-A96B-8063CAF0476D]@0xffffff7f80f17000
dependency: com.apple.iokit.IOReportFamily(47)[72B53B80-5713-30C1-BAD8-9D55FD718DA2]@0xffffff7f810d3000

BSD process name corresponding to current thread: kernel_task
Boot args: keepsyms=1 agdpmod=pikera shikigva=80

Mac OS version:
19H15

Kernel version:
Darwin Kernel Version 19.6.0: Thu Oct 29 22:56:45 PDT 2020; root:xnu-6153.141.2.2~1/RELEASE_X86_64
Kernel UUID: 9B5A7191-5B84-3990-8710-D9BD9273A8E5
__HIB text base: 0xffffff8000100000
System model name: iMac19,1 (Mac-AA95B1DDAB278B95)
System shutdown begun: YES
Panic diags file available: YES (0x0)

System uptime in nanoseconds: 81836972997
last loaded kext at 31787099012: >!AHIDKeyboard 209 (addr 0xffffff7f83d6e000, size 45056)
loaded kexts:
com.intel.driver.EnergyDriver 3.7.0
as.acidanthera.mieze.!IMausi 1.0.4
ru.joedm.SMCSuperIO 1.1.8
as.vit9696.SMCProcessor 1.1.8
as.vit9696.VirtualSMC 1.1.8
as.vit9696.WhateverGreen 1.4.4
as.vit9696.!AALC 1.5.4
as.vit9696.Lilu 1.4.9
>AudioAUUC 1.70
>!AUpstreamUserClient 3.6.8
>!AMCCSControl 1.14
@kext.AMDFramebuffer 3.1.0
>!AHDAHardwareConfigDriver 283.15
>!AHDA 283.15
@fileutil 20.036.15
@filesystems.autofs 3.0
>!APlatformEnabler 2.7.0d0
>AGPM 111.4.4
>X86PlatformShim 1.0.0
@kext.AMDRadeonX4000 3.1.0
@kext.AMDRadeonServiceManager 3.1.0
>!AGraphicsDevicePolicy 5.2.6
@AGDCPluginDisplayMetrics 5.2.6
>!A!IKBLGraphics 14.0.7
>!A!ICFLGraphicsFramebuffer 14.0.7
>!AFIVRDriver 4.1.0
@kext.AMD9500!C 3.1.0
>!A!IPCHPMC 2.0.1
>!AGFXHDA 100.1.429
>!AHV 1
|IOUserEthernet 1.0.1
|IO!BSerialManager 7.0.6f7
>pmtelemetry 1
@Dont_Steal_Mac_OS_X 7.0.0
>!A!ISlowAdaptiveClocking 4.0.0
>ACPI_SMC_PlatformPlugin 1.0.0
@private.KextAudit 1.0
|IO!BUSBDFU 7.0.6f7
>!AFileSystemDriver 3.0.1
>!AVirtIO 1.0
@filesystems.hfs.kext 522.100.5
@!AFSCompression.!AFSCompressionTypeDataless 1.0.0d1
@BootCache 40
@!AFSCompression.!AFSCompressionTypeZlib 1.0.0
@filesystems.apfs 1412.141.1
>AirPort.BrcmNIC 1400.1.1
>!AAHCIPort 341.140.1
>!ARTC 2.0
>!AACPIButtons 6.1
>!AHPET 1.8
>!ASMBIOS 2.1
>!AAPIC 1.7
$!AImage4 1
@nke.applicationfirewall 303
$TMSafetyNet 8
@!ASystemPolicy 2.0.0
|EndpointSecurity 1
>!AHIDKeyboard 209
>IO!BHIDDriver 7.0.6f7
>!ASMBus!C 1.0.18d1
|IOSMBus!F 1.1
>DspFuncLib 283.15
@kext.OSvKernDSPLib 529
@kext.triggers 1.0
@kext.AMDRadeonX4000HWLibs 1.0
@kext.AMDRadeonX4000HWServices 3.1.0
>!AGraphicsControl 5.2.6
>!AHDA!C 283.15
|IOHDA!F 283.15
>!ASMBusPCI 1.0.14d1
|IOAccelerator!F2 438.7.3
@kext.AMDSupport 3.1.0
|IONDRVSupport 576.1
|IOAVB!F 850.1
@!AGPUWrangler 5.2.6
@!AGraphicsDeviceControl 5.2.6
|IOGraphics!F 576.1
|IOSlowAdaptiveClocking!F 1.0.0
>IOPlatformPluginLegacy 1.0.0
>X86PlatformPlugin 1.0.0
>IOPlatformPlugin!F 6.0.0d8
@plugin.IOgPTPPlugin 840.3
|IOEthernetAVB!C 1.1.0
|IOAHCIBlock!S 316.100.5
|Broadcom!BHost!CUSBTransport 7.0.6f7
|IO!BHost!CUSBTransport 7.0.6f7
|IO!BHost!CTransport 7.0.6f7
|IO!B!F 7.0.6f7
|IO!BPacketLogger 7.0.6f7
>usb.IOUSBHostHIDDevice 1.2
>usb.cdc 5.0.0
>usb.networking 5.0.0
>usb.!UHostCompositeDevice 1.2
>usb.!UHub 1.2
>!UMergeNub 900.4.2
|IOAudio!F 300.2
@vecLib.kext 1.2.0
|IOSerial!F 11
|IOSurface 269.11
@filesystems.hfs.encodings.kext 1
>usb.!UHostPacketFilter 1.0
|IOUSB!F 900.4.2
>!AXsanScheme 3
|IO80211!F 1200.12.2b1
>mDNSOffloadUserClient 1.0.1b8
>corecapture 1.0.4
|IONVMe!F 2.1.0
>!AEFINVRAM 2.1
|IOSkywalk!F 1
|IOAHCI!F 290.0.1
>usb.!UXHCIPCI 1.2
>usb.!UXHCI 1.2
>!AEFIRuntime 2.1
|IOHID!F 2.0.0
$quarantine 4
$sandbox 300.0
@kext.!AMatch 1.0.0d1
>DiskImages 493.0.0
>!AFDEKeyStore 28.30
>!AEffaceable!S 1.0
>!ASSE 1.0
>!AKeyStore 2
>!UTDM 489.120.1
|IOSCSIBlockCommandsDevice 422.120.3
>!ACredentialManager 1.0
>KernelRelayHost 1
>!ASEPManager 1.0.1
>IOSlaveProcessor 1
|IOUSBMass!SDriver 157.140.1
|IOSCSIArchitectureModel!F 422.120.3
|IO!S!F 2.1
|IOUSBHost!F 1.2
>!UHostMergeProperties 1.2
>usb.!UCommon 1.0
>!ABusPower!C 1.0
|CoreAnalytics!F 1
>!AMobileFileIntegrity 1.0.5
@kext.CoreTrust 1
|IOTimeSync!F 840.3
|IONetworking!F 3.4
|IOReport!F 47
>!AACPIPlatform 6.1
>!ASMC 3.1.9
>watchdog 1
|IOPCI!F 2.9
|IOACPI!F 1.4
@kec.pthread 1
@kec.corecrypto 1.0
@kec.Libm 1



修复方法

见 GitHub: https://github.com/acidanthera/NVMeFix

macOS 10.15 及之前的版本可以安装在 /Library/Extensions 目录下
或者通用的方法是注入到启动器里

具体方法:

  1. 下载 NVMeFix.kext
  2. 拷贝至 /Volumes/EFI/EFI-backup/EFI/OC/Kexts 目录中
  3. 更新 config.plist 文件, 在 Kernel -> add 节点下添加如下内容:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
         <dict>
<key>Arch</key>
<string>x86_64</string>
<key>BundlePath</key>
<string>NVMeFix.kext</string>
<key>Comment</key>
<string>NVMeFix</string>
<key>Enabled</key>
<true/>
<key>ExecutablePath</key>
<string>Contents/MacOS/NVMeFix</string>
<key>MaxKernel</key>
<string></string>
<key>MinKernel</key>
<string>12.0.0</string>
<key>PlistPath</key>
<string>Contents/Info.plist</string>
</dict>

表现

系统关机偶尔会变成重启

解决

参考文章: https://dortania.github.io/OpenCore-Post-Install/usb/misc/shutdown.html
GitHub: https://github.com/dortania/OpenCore-Post-Install/blob/master/extra-files/FixShutdown-USB-SSDT.dsl
GitHub: https://github.com/dortania/OpenCore-Post-Install/blob/master/extra-files/FixShutdown-Patch.plist

需要工具:https://github.com/acidanthera/MaciASL/releases

解决思路

  1. FixShutdown-USB-SSDT.dsl 文件使用 MaciASL 编译成 FixShutdown-USB-SSDT.aml 文件
  2. FixShutdown-USB-SSDT.aml 文件添加到 ACPI
  3. 打上补丁

FixShutdown-USB-SSDT.dsl:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
DefinitionBlock ("", "SSDT", 2, "Slav", "ZPTS", 0x00000000)
{
External (_SB_.PCI0.XHC_.PMEE, FieldUnitObj)
External (ZPTS, MethodObj) // 1 Arguments

Method (_PTS, 1, NotSerialized) // _PTS: Prepare To Sleep
{
ZPTS (Arg0)
If ((0x05 == Arg0))
{
\_SB.PCI0.XHC.PMEE = Zero
}
}
}

当 ZPTS 的 Arg0 被赋值为 0x05 时(S5 状态),让 SB.PCI0.XHC 这个设备变成 0

其中 SB.PCI0.XHC 是设备位置

FixShutdown-USB-SSDT.aml 文件拷贝到 /Volumes/EFI/EFI-backup/EFI/OC/ACPI

更新 config.plist 文件:

ACPI -> Add:

1
2
3
4
5
6
7
8
<dict>
<key>Comment</key>
<string>Ensure USB is shutdown correctly</string>
<key>Enabled</key>
<true/>
<key>Path</key>
<string>FixShutdown-USB-SSDT.aml</string>
</dict>

ACPI -> Patch:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<dict>
<key>Comment</key>
<string>_PTS to ZPTS</string>
<key>Count</key>
<integer>0</integer>
<key>Enabled</key>
<true/>
<key>Find</key>
<data>X1BUUw==</data>
<key>Limit</key>
<integer>0</integer>
<key>Mask</key>
<data></data>
<key>OemTableId</key>
<data>AAAAAA==</data>
<key>Replace</key>
<data>WlBUUw==</data>
<key>ReplaceMask</key>
<data></data>
<key>Skip</key>
<integer>0</integer>
<key>TableLength</key>
<integer>0</integer>
<key>TableSignature</key>
<data>AAAAAA==</data>
</dict>

安装插件

插件地址: https://jenkinsci.github.io/dingtalk-plugin/

流水线配置

使用语法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def description = sh(returnStdout: true, script: 'mvn -q -N -Dexec.executable="echo"  -Dexec.args=\'${project.description}\'  org.codehaus.mojo:exec-maven-plugin:3.0.0:exec').trim()
dingtalk (
robot: 'id',
type: 'ACTION_CARD',
title: 'Jenkins 流水线构建提醒',
text: [
'![](http://nas.joylau.cn:5016/1920x1080?' + UUID.randomUUID().toString() + ')',
'### Jenkins 流水线构建结果',
'- 项目描述:' + description,
'- 分支名:' + env.BRANCH_NAME,
'- 构建状态:失败',
'- 构建时间:' + currentBuild.durationString
],
)

效果

Jenkins-Dingtalk

说明

Spring Boot 项目使用 ShardingSphere-JDBC,默认情况下会接管配置的全部数据源,这会导致一些问题
比如,所有的 sql 执行都会走 ShardingSphere 的分库或者分别的逻辑判断
最重要的是,ShardingSphere 不支持的 SQL 会直接报错
比如: https://shardingsphere.apache.org/document/current/cn/user-manual/shardingsphere-jdbc/unsupported-items/
还有: https://shardingsphere.apache.org/document/current/cn/features/sharding/use-norms/sql/#%E4%B8%8D%E6%94%AF%E6%8C%81%E7%9A%84sql

1
2
3
4
5
6
7
8
9
10
-- SELECT子句暂不支持使用*号简写及内置的分布式主键生成器
INSERT INTO tbl_name (col1, col2, …) SELECT * FROM tbl_name WHERE col3 = ?
-- SELECT子句暂不支持使用*号简写及内置的分布式主键生成器
REPLACE INTO tbl_name (col1, col2, …) SELECT * FROM tbl_name WHERE col3 = ?
-- 会导致全路由
SELECT * FROM tbl_name1 UNION SELECT * FROM tbl_name2 UNION
SELECT * FROM tbl_name1 UNION ALL SELECT * FROM tbl_name2 UNION ALL
SELECT * FROM tbl_name WHERE to_date(create_time, ‘yyyy-mm-dd’) = ?
-- 查询列是函数表达式时,查询列前不能使用表名;若查询表存在别名,则可使用表的别名
SELECT MAX(tbl_name.col1) FROM tbl_name

这是不能忍的情况

解决方案

官方已经给出的解决方案:
FQA

  1. 如果只有部分数据库分库分表,是否需要将不分库分表的表也配置在分片规则中?
    回答:

是的。因为ShardingSphere是将多个数据源合并为一个统一的逻辑数据源。因此即使不分库分表的部分,不配置分片规则ShardingSphere即无法精确的断定应该路由至哪个数据源。
但是ShardingSphere提供了两种变通的方式,有助于简化配置。

方法1:配置default-data-source,凡是在默认数据源中的表可以无需配置在分片规则中,ShardingSphere将在找不到分片数据源的情况下将表路由至默认数据源。

方法2:将不参与分库分表的数据源独立于ShardingSphere之外,在应用中使用多个数据源分别处理分片和不分片的情况。

方法 1 的配置方式不适合我
我选择了 方法 2
具体做法如下:

操作

依赖引入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
<version>5.0.0-beta</version>
<exclusions>
<!-- 版本太低,有安全漏洞:log4j-1.2.17.jar: CVE-2020-9488, CVE-2019-17571 ,排除掉 -->
<exclusion>
<artifactId>log4j</artifactId>
<groupId>log4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
</dependency>

项目配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
spring:
application:
name: im
datasource:
dynamic:
primary: im
strict: false
datasource:
im:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://xxxxxx:xxxx/im?useUnicode=true&characterEncoding=utf-8
type: com.zaxxer.hikari.HikariDataSource
username: xxxx
password: xxxx
shardingsphere:
datasource:
names: sharding-sphere
sharding-sphere:
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://xxxxxx:xxxx/sharding-sphere?useUnicode=true&characterEncoding=utf-8
type: com.zaxxer.hikari.HikariDataSource
username: xxxx
password: xxxx
rules:
sharding:
tables:
message:
actual-data-nodes: sharding-sphere.message_$->{0..1}_$->{2021..2030}${(1..12).collect{t ->t.toString().padLeft(2,'0')}}
table-strategy:
complex:
sharding-columns: conversation_type, timestamp
sharding-algorithm-name: message-table-strategy
sharding-algorithms:
message-table-strategy:
type: MessageComplexKeysShardingAlgorithm
props: { }
props:
sql-show: true

配置了 2 个数据库
im 为主库:正常增删改查的数据库
sharding-sphere:专为分库分表的使用的数据库

还配置一个分表规则,分表策略为自定义策略 MessageComplexKeysShardingAlgorithm

自定义策略

shardingsphere-jdbc 5.x 的分表策略使用的是 SPI 机制

具体就是在 resources/META-INF/services 目录下新增配置文件 org.apache.shardingsphere.sharding.spi.ShardingAlgorithm
将 shardingsphere-jdbc 5.x 自带的策略和自定义的策略加入进去

如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

org.apache.shardingsphere.sharding.algorithm.sharding.inline.InlineShardingAlgorithm
org.apache.shardingsphere.sharding.algorithm.sharding.mod.ModShardingAlgorithm
org.apache.shardingsphere.sharding.algorithm.sharding.mod.HashModShardingAlgorithm
org.apache.shardingsphere.sharding.algorithm.sharding.range.VolumeBasedRangeShardingAlgorithm
org.apache.shardingsphere.sharding.algorithm.sharding.range.BoundaryBasedRangeShardingAlgorithm
org.apache.shardingsphere.sharding.algorithm.sharding.datetime.AutoIntervalShardingAlgorithm
org.apache.shardingsphere.sharding.algorithm.sharding.datetime.IntervalShardingAlgorithm
org.apache.shardingsphere.sharding.algorithm.sharding.classbased.ClassBasedShardingAlgorithm
org.apache.shardingsphere.sharding.algorithm.sharding.complex.ComplexInlineShardingAlgorithm
org.apache.shardingsphere.sharding.algorithm.sharding.hint.HintInlineShardingAlgorithm

com.hfky.im.wildfirechat.msgforward.policy.MessageComplexKeysShardingAlgorithm

自定义策略如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class MessageComplexKeysShardingAlgorithm implements ComplexKeysShardingAlgorithm<Comparable<?>> {

/**
* 根据type和time分片。
*/
@Override
public Collection<String> doSharding(
Collection<String> collection, ComplexKeysShardingValue<Comparable<?>> shardingValue) {
}

@Override
public void init() {
//
}

@Override
public String getType() {
return "MessageComplexKeysShardingAlgorithm";
}

@Override
public Properties getProps() {
return ComplexKeysShardingAlgorithm.super.getProps();
}

@Override
public void setProps(Properties props) {
ComplexKeysShardingAlgorithm.super.setProps(props);
}
}

安装规则重写 doSharding 方法即可

动态多数据源配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
@Configuration
public class DataSourceConfiguration {

private final DynamicDataSourceProperties properties;

private final Map<String, DataSource> dataSources;

public DataSourceConfiguration(DynamicDataSourceProperties properties, @Lazy Map<String, DataSource> dataSources) {
this.properties = properties;
this.dataSources = dataSources;
}


/**
* 加入 shardingSphere 的数据源。
*/
@Bean
public DynamicDataSourceProvider dynamicDataSourceProvider() {
return new AbstractDataSourceProvider() {
@Override
public Map<String, DataSource> loadDataSources() {
Map<String, DataSource> dataSourceMap = new HashMap<>();
dataSourceMap.put(ShardingSphereDataSource.class.getAnnotation(DS.class).value(),
dataSources.get("shardingSphereDataSource"));
return dataSourceMap;
}
};
}

/**
* 设置主数据源。
*/
@Bean
@Primary
public DataSource dataSource() {
DynamicRoutingDataSource dataSource = new DynamicRoutingDataSource();
dataSource.setPrimary(properties.getPrimary());
dataSource.setStrict(properties.getStrict());
dataSource.setStrategy(properties.getStrategy());
dataSource.setP6spy(properties.getP6spy());
dataSource.setSeata(properties.getSeata());
return dataSource;
}
}

2 个注解用来切换数据源

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@DS("im")
public @interface ImDataSource {
}


@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@DS("sharding-sphere")
public @interface ShardingSphereDataSource {
}

使用方法

是需要使用数据源的 Mapper 或者 Service 加入 @ImDataSource 注解 或者 @ShardingSphereDataSource 注解, 不加的话使用的是默认数据源 im
如上配置的话,正常使用用的就是 im 数据库,分库分表使用的就是 sharding-sphere 数据库

使用 Maven 的 exec 插件

有时候我们需要使用 mvn 命令获取 maven 项目的一些信息, 比如版本号, 项目名称,项目描述等,除了解析 pom.xml 文件,还可以使用以下
命令来获取这些信息

1
mvn -q -N -Dexec.executable="echo"  -Dexec.args='${project.description}'  org.codehaus.mojo:exec-maven-plugin:3.0.0:exec
0%