创建和注销方法同时联动SmsLoad中的负载均衡实例的增减,防止因一方配置注销而负载均衡器中未注销导致的异常问题

This commit is contained in:
wind 2023-07-31 11:28:21 +08:00
parent d808332e01
commit 93d8f4bcb6
2 changed files with 56 additions and 26 deletions

View File

@ -40,7 +40,7 @@ public abstract class SmsFactory {
/** /**
* createSmsBlend * createSmsBlend
* <p>获取各个厂商的实现类 * <p>创建各个厂商的实现类
* *
* @param config 短信配置 * @param config 短信配置
* @author :Wind * @author :Wind
@ -55,13 +55,14 @@ public abstract class SmsFactory {
/** /**
* createSmsBlend * createSmsBlend
* <p> 创建一个指定厂商开启短信拦截后的实例isRestricted为true时创建出来的实例带有短信拦截性质拦截的参数取决于配置文件 * <p> 创建一个指定厂商开启短信拦截后的实例isRestricted为true时创建出来的实例带有短信拦截性质拦截的参数取决于配置文件
* @param config 短信配置 *
* @param config 短信配置
* @param isRestricted 是否为开启了短信拦截的实例 * @param isRestricted 是否为开启了短信拦截的实例
* @author :Wind * @author :Wind
*/ */
public static SmsBlend createSmsBlend(SupplierConfig config, Boolean isRestricted) { public static SmsBlend createSmsBlend(SupplierConfig config, Boolean isRestricted) {
SmsBlend sms = create(config); SmsBlend sms = create(config);
if(isRestricted){ if (isRestricted) {
sms = renderWithRestricted(sms); sms = renderWithRestricted(sms);
} }
register(sms); register(sms);
@ -71,26 +72,25 @@ public abstract class SmsFactory {
private static SmsBlend create(SupplierConfig config) { private static SmsBlend create(SupplierConfig config) {
BaseProviderFactory factory = ProviderFactoryHolder.requireForConfig(config); BaseProviderFactory factory = ProviderFactoryHolder.requireForConfig(config);
if(factory == null) { if (factory == null) {
throw new SmsBlendException("不支持当前供应商配置"); throw new SmsBlendException("不支持当前供应商配置");
} }
return factory.createSms(config); return factory.createSms(config);
} }
/**
* renderWithRestricted
* <p> 构建smsBlend对象的代理对象
* @author :Wind
*/
private static SmsBlend renderWithRestricted(SmsBlend sms) { private static SmsBlend renderWithRestricted(SmsBlend sms) {
SmsInvocationHandler smsInvocationHandler = SmsInvocationHandler.newSmsInvocationHandler( SmsInvocationHandler smsInvocationHandler = SmsInvocationHandler.newSmsInvocationHandler(sms, BeanFactory.getSmsConfig());
sms, return (SmsBlend) Proxy.newProxyInstance(sms.getClass().getClassLoader(), new Class[]{SmsBlend.class}, smsInvocationHandler);
BeanFactory.getSmsConfig()
);
return (SmsBlend) Proxy.newProxyInstance(
sms.getClass().getClassLoader(),
new Class[]{SmsBlend.class},
smsInvocationHandler
);
} }
/** /**
* 通过configId获取短信服务对象 * 通过configId获取短信服务对象
*
* @param configId 唯一标识 * @param configId 唯一标识
* @return 返回短信服务对象如果未找到则返回null * @return 返回短信服务对象如果未找到则返回null
*/ */
@ -100,37 +100,35 @@ public abstract class SmsFactory {
/** /**
* 通过供应商标识获取首个短信服务对象 * 通过供应商标识获取首个短信服务对象
*
* @param supplier 供应商标识 * @param supplier 供应商标识
* @return 返回短信服务对象如果未找到则返回null * @return 返回短信服务对象如果未找到则返回null
*/ */
public static SmsBlend getFirstBySupplier(String supplier) { public static SmsBlend getFirstBySupplier(String supplier) {
if(StrUtil.isEmpty(supplier)) { if (StrUtil.isEmpty(supplier)) {
throw new SmsBlendException("供应商标识不能为空"); throw new SmsBlendException("供应商标识不能为空");
} }
return blends.values().stream() return blends.values().stream().filter(smsBlend -> supplier.equals(smsBlend.getSupplier())).findFirst().orElse(null);
.filter(smsBlend -> supplier.equals(smsBlend.getSupplier()))
.findFirst()
.orElse(null);
} }
/** /**
* 通过供应商标识获取短信服务对象列表 * 通过供应商标识获取短信服务对象列表
*
* @param supplier 供应商标识 * @param supplier 供应商标识
* @return 返回短信服务对象列表如果未找到则返回空列表 * @return 返回短信服务对象列表如果未找到则返回空列表
*/ */
public static List<SmsBlend> getListBySupplier(String supplier) { public static List<SmsBlend> getListBySupplier(String supplier) {
List<SmsBlend> list = new ArrayList<>(); List<SmsBlend> list = new ArrayList<>();
if(StrUtil.isEmpty(supplier)) { if (StrUtil.isEmpty(supplier)) {
throw new SmsBlendException("供应商标识不能为空"); throw new SmsBlendException("供应商标识不能为空");
} }
list = blends.values().stream() list = blends.values().stream().filter(smsBlend -> supplier.equals(smsBlend.getSupplier())).collect(Collectors.toList());
.filter(smsBlend -> supplier.equals(smsBlend.getSupplier()))
.collect(Collectors.toList());
return list; return list;
} }
/** /**
* 通过负载均衡服务获取短信服务对象 * 通过负载均衡服务获取短信服务对象
*
* @return 返回短信服务列表 * @return 返回短信服务列表
*/ */
public static SmsBlend getByLoad() { public static SmsBlend getByLoad() {
@ -139,6 +137,7 @@ public abstract class SmsFactory {
/** /**
* 获取全部短信服务对象 * 获取全部短信服务对象
*
* @return 短信服务对象列表 * @return 短信服务对象列表
*/ */
public static List<SmsBlend> getAll() { public static List<SmsBlend> getAll() {
@ -147,10 +146,11 @@ public abstract class SmsFactory {
/** /**
* 注册短信服务对象 * 注册短信服务对象
*
* @param smsBlend 短信服务对象 * @param smsBlend 短信服务对象
*/ */
public static void register(SmsBlend smsBlend) { public static void register(SmsBlend smsBlend) {
if(smsBlend == null) { if (smsBlend == null) {
throw new SmsBlendException("短信服务对象不能为空"); throw new SmsBlendException("短信服务对象不能为空");
} }
blends.put(smsBlend.getConfigId(), smsBlend); blends.put(smsBlend.getConfigId(), smsBlend);
@ -158,25 +158,50 @@ public abstract class SmsFactory {
/** /**
* 以configId为标识当短信服务对象不存在时进行注册 * 以configId为标识当短信服务对象不存在时进行注册
*
* @param smsBlend 短信服务对象 * @param smsBlend 短信服务对象
* @return 是否注册成功 * @return 是否注册成功
* <p>当对象不存在时进行注册并返回true</p> * <p>当对象不存在时进行注册并返回true</p>
* <p>当对象已存在时返回false</p> * <p>当对象已存在时返回false</p>
*/ */
public static boolean registerIfAbsent(SmsBlend smsBlend) { public static boolean registerIfAbsent(SmsBlend smsBlend) {
if(smsBlend == null) { if (smsBlend == null) {
throw new SmsBlendException("短信服务对象不能为空"); throw new SmsBlendException("短信服务对象不能为空");
} }
String configId = smsBlend.getConfigId(); String configId = smsBlend.getConfigId();
if(blends.containsKey(configId)) { if (blends.containsKey(configId)) {
return false; return false;
} }
blends.put(configId, smsBlend); blends.put(configId, smsBlend);
return true; return true;
} }
/**
* registerIfAbsent
* <p> 以configId为标识当短信服务对象不存在时进行注册并添加至系统的负载均衡器
* @param smsBlend 短信服务对象
* @param weight 权重
* @return 是否注册成功
* <p>当对象不存在时进行注册并返回true</p>
* <p>当对象已存在时返回false</p>
* @author :Wind
*/
public static boolean registerIfAbsent(SmsBlend smsBlend,Integer weight) {
if (smsBlend == null) {
throw new SmsBlendException("短信服务对象不能为空");
}
String configId = smsBlend.getConfigId();
if (blends.containsKey(configId)) {
return false;
}
blends.put(configId, smsBlend);
SmsLoad.starConfig(smsBlend,weight);
return true;
}
/** /**
* 注销短信服务对象 * 注销短信服务对象
*<p>与此同时会注销掉负载均衡器中已经存在的对象</p>
* @param configId 标识 * @param configId 标识
* @return 是否注销成功 * @return 是否注销成功
* <p>当configId存在时进行注销并返回true</p> * <p>当configId存在时进行注销并返回true</p>
@ -184,6 +209,7 @@ public abstract class SmsFactory {
*/ */
public static boolean unregister(String configId) { public static boolean unregister(String configId) {
SmsBlend blend = blends.remove(configId); SmsBlend blend = blends.remove(configId);
SmsLoad.getBeanLoad().removeLoadServer(blend);
return blend != null; return blend != null;
} }

View File

@ -100,6 +100,10 @@ public class SmsLoad {
smsLoad.addLoadServer(smsBlend, Integer.parseInt(weight.toString())); smsLoad.addLoadServer(smsBlend, Integer.parseInt(weight.toString()));
} }
public static void starConfig(SmsBlend smsBlend,Integer weight) {
smsLoad.addLoadServer(smsBlend,weight);
}
public static SmsLoad getBeanLoad() { public static SmsLoad getBeanLoad() {
return smsLoad; return smsLoad;
} }