GitHub轻松阅读微服务实战项目流程详解第四天:账户服务的设计与实现

Posted Roninaxious

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GitHub轻松阅读微服务实战项目流程详解第四天:账户服务的设计与实现相关的知识,希望对你有一定的参考价值。


github地址:https://github.com/Zealon159/light-reading-cloud


1.配置文件精解

(1)boootstrap.yml

spring:
  # 服务逻辑名称
  application:
    name: light-reading-cloud-account

  cloud:
    nacos:
      # 配置中心
      config:
        server-addr: xxxxx
        file-extension: yml
        refresh: true
        shared-dataids: light-reading-cloud-account.yml  # Data ID
        namespace: 4d109a4d-f34d-4e86-9e39-c2d36db24b00  #命名空间

      # 注册中心
      discovery:
        server-addr: xxxxxx
        namespace: 4d109a4d-f34d-4e86-9e39-c2d36db24b00

(2)配置中心的yml文件

2.Config

当然在配置文件更方便,以下使用配置类进行配置

(1)书架线程池配置

@Configuration
@ConfigurationProperties(prefix = "spring.thread-pool.bookshelf")
public class BookshelfThreadPoolConfig {

    /** 核心线程数 */
    private int corePoolSize;
    /** 最大线程数 */
    private int maximumPoolSize;
    /** 线程存活时间 */
    private Long keepAliveTime;
    /** 队列容量 */
    private int queueCapacity;

    /**
     * 云书架数据消费线程池
     * @return
     */
    @Bean(value = "userBookshelfQueueThreadPool")
    public ExecutorService buildUserBookshelfQueueThreadPool(){
        ThreadFactory namedThreadFactory = new ThreadFactoryBuilder()
                .setNameFormat("user-bookshelf-queue-thread-%d").build();
        // 实例化线程池
        ExecutorService pool = new ThreadPoolExecutor(this.getCorePoolSize(), this.getMaximumPoolSize(), this.getKeepAliveTime(), TimeUnit.MILLISECONDS,
                new ArrayBlockingQueue<>(this.getQueueCapacity()),namedThreadFactory,new ThreadPoolExecutor.AbortPolicy());
        return pool;
    }

    public int getCorePoolSize() {
        return corePoolSize;
    }

    public void setCorePoolSize(int corePoolSize) {
        this.corePoolSize = corePoolSize;
    }

    public int getMaximumPoolSize() {
        return maximumPoolSize;
    }

    public void setMaximumPoolSize(int maximumPoolSize) {
        this.maximumPoolSize = maximumPoolSize;
    }

    public Long getKeepAliveTime() {
        return keepAliveTime;
    }

    public void setKeepAliveTime(Long keepAliveTime) {
        this.keepAliveTime = keepAliveTime;
    }

    public int getQueueCapacity() {
        return queueCapacity;
    }

    public void setQueueCapacity(int queueCapacity) {
        this.queueCapacity = queueCapacity;
    }
}

(2)Mybatis及其Swagger配置

@Configuration
@MapperScan(basePackages = "cn.zealon.readingcloud.account.dao",
        sqlSessionTemplateRef="accountCenterSqlSessionTemplate")
public class MybatisConfig {

    private final static String MAPPER_LOCATIONS = "classpath*:mappers/*.xml";

    /** 工厂配置 */
    @Bean
    public SqlSessionFactory sqlSessionFactoryBean(@Qualifier("accountCenterDataSource") DataSource dataSource) throws Exception {
        // 设置数据源
        SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
        factory.setDataSource(dataSource);

        // 添加XML映射
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        factory.setMapperLocations(resolver.getResources(MAPPER_LOCATIONS));

        //添加插件
        factory.setPlugins(new Interceptor[]{ this.getPageHelper() });
        return factory.getObject();
    }

    /** 会话模板 */
    @Bean(name = "accountCenterSqlSessionTemplate")
    public SqlSessionTemplate setSqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }

    /** 分页插件 */
    private PageHelper getPageHelper(){
        //配置分页插件,详情请查阅官方文档
        PageHelper pageHelper = new PageHelper();
        Properties properties = new Properties();
        //分页尺寸为0时查询所有纪录不再执行分页
        properties.setProperty("pageSizeZero", "true");
        //页码<=0 查询第一页,页码>=总页数查询最后一页
        properties.setProperty("reasonable", "true");
        //支持通过 Mapper 接口参数来传递分页参数
        properties.setProperty("supportMethodsArguments", "true");
        properties.setProperty("params", "count=countSql");
        //切换数据源,自动解析不同数据库的分页
        properties.setProperty("autoRuntimeDialect", "true");
        pageHelper.setProperties(properties);
        return pageHelper;
    }

    /**
     * swagger 配置类
     * http://localhost:8080/swagger-ui.html
     * @author zealon
     * @since 2019-07-04
     */
    @Configuration
    @EnableSwagger2
    public static class AccountSwaggerConfig {

        /**
         * swagger生成
         * @return Docket
         */
        @Bean
        public Docket customDocket() {
            Docket docket = new Docket(DocumentationType.SWAGGER_2)
                    .select()
                    .apis(RequestHandlerSelectors.basePackage("cn.zealon.readingcloud.account.controller"))
                    .paths(PathSelectors.any())
                    .build()
                    .apiInfo(apiInfo());
            return docket;
        }

        /**
         * swagger基础信息
         * @return ApiInfo swagger信息
         */
        private ApiInfo apiInfo() {
            return new ApiInfoBuilder()
                    .title("账户中心接口")
                    .description("账户中心")
                    .termsOfServiceUrl("")
                    .contact(new Contact("", "", ""))
                    .license("")
                    .licenseUrl("")
                    .version("1.0.0")
                    .build();
        }
    }
}

(3)Redis配置

@EnableCaching
@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> redis = new RedisTemplate<>();
        redis.setConnectionFactory(redisConnectionFactory);
        this.setSerializer(redis);
        return redis;
    }

    /** 配置Key的生成方式 */
    @Bean
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object o, Method method, Object... objects) {
                StringBuilder stringBuilder = new StringBuilder();
                stringBuilder.append(o.getClass().getName()).append(method.getName());
                for (Object object : objects) {
                    stringBuilder.append(object.toString());
                }
                return stringBuilder.toString();
            }
        };
    }

    /** 缓存管理器 */
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
        //初始化一个RedisCacheWriter
        RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory);
        //设置CacheManager的值序列化方式为json序列化
        RedisSerializer<Object> jsonSerializer = new GenericJackson2JsonRedisSerializer();
        RedisSerializationContext.SerializationPair<Object> pair = RedisSerializationContext.SerializationPair.fromSerializer(jsonSerializer);
        RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig().serializeValuesWith(pair);
        //设置默认超过期时间是30秒
        defaultCacheConfig = defaultCacheConfig.entryTtl(Duration.ofSeconds(300));
        //初始化RedisCacheManager
        return new RedisCacheManager(redisCacheWriter, defaultCacheConfig);
    }

    /** 设置RedisTemplate的序列化方式 */
    public void setSerializer(RedisTemplate redisTemplate) {
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        //设置键(key)的序列化方式
        redisTemplate.setKeySerializer(stringRedisSerializer);
        //设置值(value)的序列化方式
        redisTemplate.setHashKeySerializer(stringRedisSerializer);
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.afterPropertiesSet();
    }
}

(4)公用线程池配置

@Configuration
@ConfigurationProperties(prefix = "spring.thread-pool.common")
public class ThreadPoolConfig {

    /** 核心线程数 */
    private int corePoolSize;
    /** 最大线程数 */
    private int maximumPoolSize;
    /** 线程存活时间 */
    private Long keepAliveTime;
    /** 队列容量 */
    private int queueCapacity;

    /**
     * 云书架数据消费线程池
     * @return
     */
    @Bean(value = "commonQueueThreadPool")
    public ExecutorService buildCommonQueueThreadPool(){
        ThreadFactory namedThreadFactory = new ThreadFactoryBuilder()
                .setNameFormat("common-queue-thread-%d").build();
        // 实例化线程池
        ExecutorService pool = new ThreadPoolExecutor(this.getCorePoolSize(), this.getMaximumPoolSize(), this.getKeepAliveTime(), TimeUnit.MILLISECONDS,
                new ArrayBlockingQueue<>(this.getQueueCapacity()),namedThreadFactory,new ThreadPoolExecutor.AbortPolicy());
        return pool;
    }

    public int getCorePoolSize() {
        return corePoolSize;
    }

    public void setCorePoolSize(int corePoolSize) {
        this.corePoolSize = corePoolSize;
    }

    public int getMaximumPoolSize() {
        return maximumPoolSize;
    }

    public void setMaximumPoolSize(int maximumPoolSize) {
        this.maximumPoolSize = maximumPoolSize;
    }

    public Long getKeepAliveTime() {
        return keepAliveTime;
    }

    public void setKeepAliveTime(Long keepAliveTime) {
        this.keepAliveTime = keepAliveTime;
    }

    public int getQueueCapacity() {
        return queueCapacity;
    }

    public void setQueueCapacity(int queueCapacity) {
        this.queueCapacity = queueCapacity;
    }
}

(5)数据源配置

@Configuration
public class AccountCenterDataSourceConfig {

    /** 数据源Bean */
    @Bean(name = "accountCenterDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.account-center")
    public DataSource accountCenterDataSource(){
        return new DruidDataSource();
    }

    /** 事务管理器 */
    @Bean(name = "accountCenterTransactionManager")
    public DataSourceTransactionManager setTransactionManager(@Qualifier("accountCenterDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}

以上是关于GitHub轻松阅读微服务实战项目流程详解第四天:账户服务的设计与实现的主要内容,如果未能解决你的问题,请参考以下文章

GitHub轻松阅读微服务实战项目流程详解第二天:API网关的设计与实现

GitHub轻松阅读微服务实战项目流程详解第三天:公共模块的设计与实现

Spring Cloud 微服务实战

Spring Cloud微服务实战

SpringCloud微服务实战学习系列配置详解

Docker详解与部署微服务实战