Skip to content

ZebraSpi扩展说明

junior_xin edited this page Dec 5, 2018 · 2 revisions

ZebraSpi扩展文档

1.ConfigService扩展

1.1介绍

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);
}

1.2如何扩展

ConfigService使用Spi的方式进行加载

(1)实现ConfigService:

我们提供了以个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() {
	}
}

(2)添加Spi注解

Spi注解由2个参数构成:
name(必填): 指定ConfigService的name,默认为"", name应保证唯一。
scope : 指定ConfigService是否为单例,不填默认为单例。

@Spi(name = "demo", scope = Scope.SINGLETON)

(3)注册

Spi的类加载文件放置在 META-INF/services/com.dianping.zebra.config.ConfigService文件中,开发者将自定义的ConfigService路径填入其中即可。

com.dianping.zebra.config.ZookeeperConfigService
com.dianping.zebra.config.PropertyConfigService

(4)使用

以上配置完成后,需要在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()

2.filter扩展

2.1介绍

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);
}

2.2如何扩展

Filter使用Spi的方式进行扩展

(1)实现Filter接口:

一般继承DefaultJdbcFilter即可,Zebra默认提供wallFilter和CatFilter,开发者可以进行参考

public class WallFilter extends DefaultJdbcFilter

(2)注册:

Filter的类加载文件放置在META-INF/zebra-filter.properties目录下,格式为
zebra.filter.${filterName} = 类路径

zebra.filter.wall=com.dianping.zebra.filter.wall.WallFilter

(3)使用

以上配置完成后,需要在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()
Clone this wiki locally