Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
apache
Shardingsphere
提交
f5d40257
Shardingsphere
项目概览
apache
/
Shardingsphere
通知
56
Star
3
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
Shardingsphere
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
f5d40257
编写于
7月 27, 2017
作者:
C
chengcheng.feng
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
IPSectionKeyGenerator
上级
eda72045
变更
2
显示空白变更内容
内联
并排
Showing
2 changed file
with
184 addition
and
0 deletion
+184
-0
sharding-jdbc-plugin/src/main/java/com/dangdang/ddframe/rdb/sharding/plugin/keygen/IPSectionKeyGenerator.java
...ame/rdb/sharding/plugin/keygen/IPSectionKeyGenerator.java
+62
-0
sharding-jdbc-plugin/src/test/java/com/dangdang/ddframe/rdb/sharding/plugin/keygen/IPSectionKeyGeneratorTest.java
...rdb/sharding/plugin/keygen/IPSectionKeyGeneratorTest.java
+122
-0
未找到文件。
sharding-jdbc-plugin/src/main/java/com/dangdang/ddframe/rdb/sharding/plugin/keygen/IPSectionKeyGenerator.java
0 → 100644
浏览文件 @
f5d40257
package
com.dangdang.ddframe.rdb.sharding.plugin.keygen
;
import
com.dangdang.ddframe.rdb.sharding.keygen.DefaultKeyGenerator
;
import
com.dangdang.ddframe.rdb.sharding.keygen.KeyGenerator
;
import
java.net.InetAddress
;
import
java.net.UnknownHostException
;
/**
* 浏览 {@link IPKeyGenerator} workerId生成的规则后,感觉对服务器IP后10位(特别是IPV6)数值比较约束。
* 有以下优化思路:
* 因为workerId最大限制是2^10,我们生成的workerId只要满足小于最大workerId即可。
* 1.针对IPV4:
* ....IP最大 255.255.255.255。而(255+255+255+255) < 1024。
* ....因此采用IP段数值相加即可生成唯一的workerId,不受IP位限制。
* 2.针对IPV6:
* ....IP最大ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
* ....为了保证相加生成出的workerId < 1024,思路是将每个bit位的后6位相加。这样在一定程度上也可以满足workerId不重复的问题。
* <p/>
* <p/>
* 使用这种IP生成workerId的方法,必须保证IP段相加不能重复
*
* @author DogFc
*/
public
class
IPSectionKeyGenerator
implements
KeyGenerator
{
private
final
DefaultKeyGenerator
defaultKeyGenerator
=
new
DefaultKeyGenerator
();
static
{
initWorkerId
();
}
static
void
initWorkerId
()
{
InetAddress
address
;
try
{
address
=
InetAddress
.
getLocalHost
();
}
catch
(
final
UnknownHostException
e
)
{
throw
new
IllegalStateException
(
"Cannot get LocalHost InetAddress, please check your network!"
);
}
byte
[]
ipAddressByteArray
=
address
.
getAddress
();
long
workerId
=
0L
;
//IPV4
if
(
ipAddressByteArray
.
length
==
4
)
{
for
(
byte
byteNum
:
ipAddressByteArray
)
{
workerId
+=
(
byteNum
&
0xFF
);
}
//IPV6
}
else
if
(
ipAddressByteArray
.
length
==
16
)
{
for
(
byte
byteNum
:
ipAddressByteArray
)
{
workerId
+=
(
byteNum
&
0B111111
);
}
}
else
{
throw
new
IllegalStateException
(
"Bad LocalHost InetAddress, please check your network!"
);
}
DefaultKeyGenerator
.
setWorkerId
(
workerId
);
}
@Override
public
Number
generateKey
()
{
return
defaultKeyGenerator
.
generateKey
();
}
}
sharding-jdbc-plugin/src/test/java/com/dangdang/ddframe/rdb/sharding/plugin/keygen/IPSectionKeyGeneratorTest.java
0 → 100644
浏览文件 @
f5d40257
/*
* Copyright 1999-2015 dangdang.com.
* <p>
* Licensed 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.
* </p>
*/
package
com.dangdang.ddframe.rdb.sharding.plugin.keygen
;
import
com.dangdang.ddframe.rdb.sharding.keygen.DefaultKeyGenerator
;
import
org.junit.BeforeClass
;
import
org.junit.FixMethodOrder
;
import
org.junit.Rule
;
import
org.junit.Test
;
import
org.junit.rules.ExpectedException
;
import
org.junit.runner.RunWith
;
import
org.junit.runners.MethodSorters
;
import
org.powermock.api.mockito.PowerMockito
;
import
org.powermock.core.classloader.annotations.PrepareForTest
;
import
org.powermock.modules.junit4.PowerMockRunner
;
import
java.lang.reflect.Field
;
import
java.net.InetAddress
;
import
java.net.UnknownHostException
;
import
java.util.HashSet
;
import
java.util.Set
;
import
java.util.concurrent.Callable
;
import
java.util.concurrent.ExecutorService
;
import
java.util.concurrent.Executors
;
import
static
org
.
hamcrest
.
core
.
Is
.
is
;
import
static
org
.
junit
.
Assert
.
assertThat
;
@RunWith
(
PowerMockRunner
.
class
)
@PrepareForTest
(
IPSectionKeyGenerator
.
class
)
@FixMethodOrder
(
MethodSorters
.
NAME_ASCENDING
)
@SuppressWarnings
(
"all"
)
public
class
IPSectionKeyGeneratorTest
{
private
static
InetAddress
ipv4Address
;
private
static
InetAddress
ipv6Address
;
@Rule
public
ExpectedException
exception
=
ExpectedException
.
none
();
@BeforeClass
public
static
void
init
()
throws
UnknownHostException
{
String
ipv4
=
"192.168.1.1"
;
byte
[]
ipv4Byte
=
new
byte
[
4
];
String
[]
ipv4StingArray
=
ipv4
.
split
(
"\\."
);
for
(
int
i
=
0
;
i
<
4
;
i
++)
{
ipv4Byte
[
i
]
=
(
byte
)
Integer
.
valueOf
(
ipv4StingArray
[
i
]).
intValue
();
}
ipv4Address
=
InetAddress
.
getByAddress
(
"dangdang-db-sharding-dev-233"
,
ipv4Byte
);
String
ipv6
=
"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"
;
ipv6Address
=
InetAddress
.
getByName
(
ipv6
);
}
@Test
public
void
testIPV4
()
throws
UnknownHostException
,
NoSuchFieldException
,
IllegalAccessException
{
PowerMockito
.
mockStatic
(
InetAddress
.
class
);
PowerMockito
.
when
(
InetAddress
.
getLocalHost
()).
thenReturn
(
ipv4Address
);
IPSectionKeyGenerator
.
initWorkerId
();
Field
workerIdField
=
DefaultKeyGenerator
.
class
.
getDeclaredField
(
"workerId"
);
workerIdField
.
setAccessible
(
true
);
assertThat
(
workerIdField
.
getLong
(
DefaultKeyGenerator
.
class
),
is
(
362L
));
}
@Test
public
void
testIPV6
()
throws
UnknownHostException
,
NoSuchFieldException
,
IllegalAccessException
{
PowerMockito
.
mockStatic
(
InetAddress
.
class
);
PowerMockito
.
when
(
InetAddress
.
getLocalHost
()).
thenReturn
(
ipv6Address
);
IPSectionKeyGenerator
.
initWorkerId
();
Field
workerIdField
=
DefaultKeyGenerator
.
class
.
getDeclaredField
(
"workerId"
);
workerIdField
.
setAccessible
(
true
);
assertThat
(
workerIdField
.
getLong
(
DefaultKeyGenerator
.
class
),
is
(
1008L
));
}
@Test
public
void
testUnknownHost
()
throws
UnknownHostException
{
PowerMockito
.
mockStatic
(
InetAddress
.
class
);
PowerMockito
.
when
(
InetAddress
.
getLocalHost
()).
thenThrow
(
new
UnknownHostException
());
exception
.
expect
(
IllegalStateException
.
class
);
exception
.
expectMessage
(
"Cannot get LocalHost InetAddress, please check your network!"
);
IPSectionKeyGenerator
.
initWorkerId
();
}
@Test
public
void
generateId
()
throws
Exception
{
PowerMockito
.
mockStatic
(
InetAddress
.
class
);
PowerMockito
.
when
(
InetAddress
.
getLocalHost
()).
thenReturn
(
ipv4Address
);
IPSectionKeyGenerator
.
initWorkerId
();
int
threadNumber
=
Runtime
.
getRuntime
().
availableProcessors
()
<<
1
;
ExecutorService
executor
=
Executors
.
newFixedThreadPool
(
threadNumber
);
final
int
taskNumber
=
threadNumber
<<
2
;
final
IPSectionKeyGenerator
ipSectionKeyGenerator
=
new
IPSectionKeyGenerator
();
Set
<
Long
>
hashSet
=
new
HashSet
<>();
for
(
int
i
=
0
;
i
<
taskNumber
;
i
++)
{
hashSet
.
add
(
executor
.
submit
(
new
Callable
<
Long
>()
{
@Override
public
Long
call
()
throws
Exception
{
return
(
Long
)
ipSectionKeyGenerator
.
generateKey
();
}
}).
get
());
}
assertThat
(
hashSet
.
size
(),
is
(
taskNumber
));
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录