-
Notifications
You must be signed in to change notification settings - Fork 717
ZebraSpi扩展说明
Zebra的ConfigsService是一个可扩展的配置加载接口,通过扩展ConfigService,用户可以自己定制配置获取的方式。 Zebra默认提供2种ConfigService,本地的PropertiesConfigService和ZookeeperConfigService。
package com.dianping.zebra.config;
public interface ConfigService {
//init方法 Spi机制会直接返回类的实例,故在init时进行相关配置初始化操作
public void init(Map<String, Object> serviceConfigs);
//销毁
public void destroy();
//通过该方法获取配置中心保存的配置,无结果返回null
public String getProperty(String key);
//添加配置变更的listerner
public void addPropertyChangeListener(PropertyChangeListener listener);
//销毁配置变更的listerner
public void removePropertyChangeListener(PropertyChangeListener listener);
}
ConfigService使用Spi的方式进行加载
我们提供了以个RemoteConfigService作为模板,开发者可以参考Zebra自身提供的PropertiesConfigService和ZookeeperConfigService进行开发。
package com.dianping.zebra.config;
@Spi(name = "demo", scope = Scope.SINGLETON)
public class RemoteConfigService implements ConfigService {
protected static final Logger logger = LoggerFactory.getLogger(RemoteConfigService.class);
protected volatile boolean init = false;
private List<PropertyChangeListener> listeners = new CopyOnWriteArrayList<PropertyChangeListener>();
// TODO customize this method to get config from remote
@Override
public String getProperty(String key) {
return null;
}
@Override
public void addPropertyChangeListener(PropertyChangeListener listener) {
listeners.add(listener);
}
@Override
public void removePropertyChangeListener(PropertyChangeListener listener) {
listeners.remove(listener);
}
// TODO customize this method
@Override
public void init(Map<String, Object> serviceConfigs) {
this.init = true;
}
// TODO customize this method
@Override
public void destroy() {
}
}
Spi注解由2个参数构成:
name(必填): 指定ConfigService的name,默认为"", name应保证唯一。
scope : 指定ConfigService是否为单例,不填默认为单例。
@Spi(name = "demo", scope = Scope.SINGLETON)
Spi的类加载文件放置在 META-INF/services/com.dianping.zebra.config.ConfigService文件中,开发者将自定义的ConfigService路径填入其中即可。
com.dianping.zebra.config.ZookeeperConfigService
com.dianping.zebra.config.PropertyConfigService
以上配置完成后,需要在Zebra的DataSource(shard/group/single)配置中进行配置使用, configManagerType设置为ConfigService的name
spring:
<bean id="dataSource" class="com.dianping.zebra.group.jdbc.GroupDataSource"
destroy-method="close" init-method="init">
<property name="jdbcRef" value="${jdbcref}"/>
<!-- 默认提供 "local","zookeeper" 2种 -->
<property name="configManagerType" value="local"/>
</bean>
java:
GroupDataSrouce ds = new GroupDataSrouce();
ds.setJdbcref(${jdbcref});
ds.setConfigManagerType("local");
ds.init()
Zebra的filter是一套sql执行过程中的扩展接口,里面包含sql执行过程中一些关键点的切面。接口位于com.dianping.zebra.filter.JdbcFilter
public interface JdbcFilter {
//优先级 默认为0, order越小 优先级越高
int DEFAULT_ORDER = 0;
int MAX_ORDER = Integer.MAX_VALUE;
int MIN_ORDER = Integer.MIN_VALUE;
/**
* filter ordering <br>
* filter_with_order_3_start filter_with_order_2_start
* filter_with_order_1_start targer_start filter_with_order_1_finish
* filter_with_order_2_finish filter_with_order_3_finish
*
* @return the order of execute
*/
int getOrder();
/**
* init filter
*/
void init();
/** GroupDataSource Filter **/
void initGroupDataSource(GroupDataSource source, JdbcFilter chain);
void refreshGroupDataSource(GroupDataSource source, String propertiesName, JdbcFilter chain);
GroupConnection getGroupConnection(GroupDataSource source, JdbcFilter chain) throws SQLException;
FailOverDataSource.FindMasterDataSourceResult findMasterFailOverDataSource(
FailOverDataSource.MasterDataSourceMonitor source, JdbcFilter chain);
void closeGroupConnection(GroupConnection source, JdbcFilter chain) throws SQLException;
void closeGroupDataSource(GroupDataSource source, JdbcFilter chain) throws SQLException;
void switchFailOverDataSource(FailOverDataSource source, JdbcFilter chain);
/** SingleDataSource Filter **/
DataSource initSingleDataSource(SingleDataSource source, JdbcFilter chain);
SingleConnection getSingleConnection(SingleDataSource source, JdbcFilter chain) throws SQLException;
String processSQL(DataSourceConfig dsConfig, SQLProcessContext ctx, JdbcFilter chain) throws SQLException;
<T> T executeSingleStatement(SingleStatement source, SingleConnection conn, String sql, List<String> batchedSql,
boolean isBatched, boolean autoCommit, Object params, JdbcFilter chain) throws SQLException;
void closeSingleConnection(SingleConnection source, JdbcFilter chain) throws SQLException;
void closeSingleDataSource(SingleDataSource source, JdbcFilter chain) throws SQLException;
void closeSingleResultSet(SingleResultSet source, JdbcFilter chain) throws SQLException;
/** ShardDataSource Filter **/
void initShardDataSource(ShardDataSource source, JdbcFilter chain);
ResultSet executeShardQuery(ShardStatement source, String sql, JdbcFilter chain) throws SQLException;
int executeShardUpdate(ShardStatement source, String sql, int autoGeneratedKeys, int[] columnIndexes,
String[] columnNames, JdbcFilter chain) throws SQLException;
void shardRouting(RouterResult rr, JdbcFilter chain) throws SQLException;
void shardMerge(ShardResultSet rs, JdbcFilter chain) throws SQLException;
void configChanged(PropertyChangeEvent evt, JdbcFilter chain);
}
Filter使用Spi的方式进行扩展
一般继承DefaultJdbcFilter即可,Zebra默认提供wallFilter和CatFilter,开发者可以进行参考
public class WallFilter extends DefaultJdbcFilter
Filter的类加载文件放置在META-INF/zebra-filter.properties目录下,格式为
zebra.filter.${filterName} = 类路径
zebra.filter.wall=com.dianping.zebra.filter.wall.WallFilter
以上配置完成后,需要在Zebra的DataSource(shard/group/single)配置中进行配置使用, filter里添加需要的filterName,默认为"wall"
spring:
<bean id="dataSource" class="com.dianping.zebra.group.jdbc.GroupDataSource"
destroy-method="close" init-method="init">
<property name="jdbcRef" value="${jdbcref}"/>
<!-- 默认提供 "local","zookeeper" 2种 -->
<property name="filter" value="wall,cat"/>
</bean>
java:
GroupDataSrouce ds = new GroupDataSrouce();
ds.setJdbcref(${jdbcref});
ds.setFilter("wall,cat");
ds.init()