当前位置: 首页 > 文档资料 > Zebra 中文文档 >

ZebraSpi 扩展说明

优质
小牛编辑
119浏览
2023-12-01

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()