技术中台战略:SpringBoot+Dubbo+Redis+MybatisPlus整合,3小时再次搞定分布式服务Demo

版权声明:襄阳雷哥的版权声明 https://blog.csdn.net/FansUnion/article/details/89288090

最近决定搭建的自己的技术中台,之前想短平快,只用本地jar包,工具类,通用代码之类的。

发现,有些场景复用不太方便。

为了长远打算,也需要搭建自己的技术中台,提供RPC和HTTP各种通用基础服务,比如内容管理等等。

也可能用本地jar包模式,直接访问数据库。

看情况吧。

------------------

搭建整合项目的过程中,遇到了太多的问题,真是累坏了。

晚饭还没吃。

不太喜欢直接照搬复制别人的代码,再修改。

第1次,不花时间,不交学费,今后遇到问题了,同样花时间。

第1次,从0开始,不断参考网友的思路,可以更全面逐步低学习。

在解决各种各样的问题中,还是有很大进步的。

有个问题值得说下,包括本文在内的文章,再总结的时候,很难面面俱到,注意到每一个细节。代码可以运行,但是懒得上传到Github上,因此参考别人的思路时,需要注意 不同文章的不同点。

每一个细节都注意到了,才学得更全面。

今后遇到各种问题都能解决。

通用问题,大家都会遇到。

一个问题可以有多种解决办法,根据自己的习惯做选择。

--------------------

核心过程

1、3个项目

公共接口实体jar包,比较简单,没技术难题

服务提供方,比较关键

服务启动方,注册消费就行

2、一些核心配置,供参考

application.yml

spring:
  profiles:
    active: dev
  dubbo:
    application.name: provider    
    registry.address: redis://47.05.919.4:6379
    registry.username: 1
    registry.password: jtn222d21
    protocol.name: dubbo 
    protocol.port: 20880
    scan: com.j.techplatform.rpc.service

@Configuration
@ComponentScan(basePackages="com.j.common.web.crud.manager.content")
public class JtnConfig {

    @Autowired
    private Environment env;

    @Bean(name = "dataSource")
    public DataSource getDataSource() throws Exception {
        Properties props = new Properties();
        props.put("driverClassName", env.getProperty("spring.datasource.driverClassName"));
        props.put("url", env.getProperty("spring.datasource.url"));
        props.put("username", env.getProperty("spring.datasource.username"));
        props.put("password", env.getProperty("spring.datasource.password"));
        return DruidDataSourceFactory.createDataSource(props);
    }

}

自己在学习研究MybatisPlus,整合进去了

import java.io.IOException;

import javax.sql.DataSource;

import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.logging.stdout.StdOutImpl;
import org.apache.ibatis.mapping.DatabaseIdProvider;
import org.apache.ibatis.plugin.Interceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.mybatis.spring.boot.autoconfigure.SpringBootVFS;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;

import com.baomidou.mybatisplus.autoconfigure.MybatisPlusProperties;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.core.MybatisXMLLanguageDriver;
import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;

@Configuration
@MapperScan(basePackages = "com.j.common.web.crud.mapper.content")
public class MybatisPlusConfig {
    @Autowired
    private DataSource dataSource;

    @Autowired
    private MybatisPlusProperties properties;

    @Autowired
    private ResourceLoader resourceLoader = new DefaultResourceLoader();

    @Autowired(required = false)
    private Interceptor[] interceptors;

    @Autowired(required = false)
    private DatabaseIdProvider databaseIdProvider;

    /**
     * mybatis-plus分页插件
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor page = new PaginationInterceptor();
        page.setDialectType("mysql");
        return page;
    }

    /**
     * 乐观锁插件
     */
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor() {
        return new OptimisticLockerInterceptor();
    }
    
    
    /**
     * 这里全部使用mybatis-autoconfigure 已经自动加载的资源。不手动指定 配置文件和mybatis-boot的配置文件同步
     */
    @Bean
    public MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean() throws IOException {
        MybatisSqlSessionFactoryBean mybatisPlus = new MybatisSqlSessionFactoryBean();
        mybatisPlus.setDataSource(dataSource);
        mybatisPlus.setVfs(SpringBootVFS.class);
        String configLocation = this.properties.getConfigLocation();
        if (StringUtils.isNotBlank(configLocation)) {
            mybatisPlus.setConfigLocation(this.resourceLoader.getResource(configLocation));
        }
        mybatisPlus.setConfiguration(properties.getConfiguration());
        mybatisPlus.setPlugins(this.interceptors);
        MybatisConfiguration mc = new MybatisConfiguration();
        mc.setDefaultScriptingLanguage(MybatisXMLLanguageDriver.class);
        // 数据库和java都是驼峰,就不需要
        mc.setMapUnderscoreToCamelCase(false);
        //开发环境打印sql
        mc.setLogImpl(StdOutImpl.class);
        mybatisPlus.setConfiguration(mc);
        
        if (this.databaseIdProvider != null) {
            mybatisPlus.setDatabaseIdProvider(this.databaseIdProvider);
        }
        mybatisPlus.setTypeAliasesPackage(this.properties.getTypeAliasesPackage());
        mybatisPlus.setTypeHandlersPackage(this.properties.getTypeHandlersPackage());
        mybatisPlus.setMapperLocations(this.properties.resolveMapperLocations());
        // 设置mapper.xml文件的路径
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        Resource[] resource = resolver.getResources("classpath:mapper/*.xml");
        mybatisPlus.setMapperLocations(resource);
        return mybatisPlus;
    }
}
 

pom.xml

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.4.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>

<!--springboot集成dubbo起步依赖-->
<dependency>
    <groupId>com.alibaba.spring.boot</groupId>
    <artifactId>dubbo-spring-boot-starter</artifactId>
    <version>2.0.0</version>
    </dependency>
             <!-- mvn spring-boot:run 热部署启动 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>springloaded</artifactId>
        </dependency>
    
        <!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>
            <!-- https://mvnrepository.com/artifact/commons-pool/commons-pool -->
        <!-- <dependency>
            <groupId>commons-pool</groupId>
            <artifactId>commons-pool</artifactId>
        </dependency> -->
        
        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-pool2 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>

4、服务提供方先启动,注意扫描到包

@Slf4j
@SpringBootApplication(scanBasePackages="com.j")
//@ServletComponentScan
//@EnableScheduling
@EnableDubboConfiguration
public class JtnTechPlatformApplication {

    public static void main(String[] args) {
        Stopwatch stopwatch = Stopwatch.createStarted();
        log.info("JtnApplication starting ...");
        SpringApplication.run(JtnTechPlatformApplication.class, args);
        log.info("JtnApplication started. 共耗时{}", stopwatch.stop().toString());
    }
}

遇到的几个问题

1、使用Redis作为注册中心,而非ZooKeeper

自己的阿里云上有现成的Redis服务,也作为缓存在用。

ZooKeeper一般作为标准的注册中心,但是自己这个整合项目,目前主要是能跑起来运行就行,非生产项目。

再搭建维护1个ZooKeeper太麻烦了。

不过话说回来,解决Redis的问题,足够搭建ZooKeeper了。

2、Redis需要使用密码和用户名

(仅供参考)

本地连不上阿里云ECS部署的Redis,提示 超时,超时不可能是密码不对的问题。

查询资料,Redis默认绑定127.0.0.1,注释掉。

设置Redis没密码。

项目能够连上了。

网友有指出Redis作为注册中心,需要设置 用户名。

有网友直接 定制源码,比如 使用1个同名的 类源码 放到自己的目录,再修改。

也有网友指出,用户名可以随便配置,我就随便写了1个,ok。

结论:Redis配置密码,取消bind 本地。

项目中配置 Redis密码,随便配置1个用户名。

3、RPC提供方正常启动,RPC消费方无法消费,提示没用可用的provider.

尝试本地运行dubbo-admin,网上下载了dubbo-admin-2.5.4。

报错,提示 用户名不能为空之类的。

参考网友资料,dubbo-admin-2.6.0之后修复了这个bug。

没用再试了,因为想起来了 RPC提供方应该有问题。

本地日志没用提到Dubbo成功注册 服务到 注册中心。

4、@EnableDubboConfiguration  dubbo的注解很关键

5、JtnPostService 是接口定义

JtnPostServiceImpl是接口实现类。

很关键,Spring的@Service和Dubbo的@Service重名了,以为只需要1个。

实际上都需要,但为了方便使用,用Dubbo的@Service,用Spring的@Component  代替Spring自己的@Service、

import org.springframework.stereotype.Component;

com.alibaba.dubbo.config.annotation.Service;

@Service
@Component 
public class JtnPostServiceImpl implements JtnPostService {

}

6、扫描包

@SpringBootApplication(scanBasePackages="com.j")

可能会有问题,手动执行,比较清晰

7、消费方,用@Reference注解。

public class PostController {

    @Reference
    //@Autowired
    private JtnPostService postService;

}

8. dubbo生产者和消费者的配置,name应该不同,没具体研究。

scan记得扫描,配置自己的包路径。

spring:
  profiles:
    active: dev
  dubbo:
    application.name: consumer    
    registry.address: redis://47.15.9.4:6379
    registry.username: 1
    registry.password: jn2213
    protocol.name: dubbo 
    protocol.port: 20880
    scan: com.j

spring:
  profiles:
    active: dev
  dubbo:
    application.name: provider    
    registry.address: redis://47.1125.99.4:6379
    registry.username: 1
    registry.password: ssdssafd
    protocol.name: dubbo 
    protocol.port: 20880
    scan: com.j.techplatform.rpc.service
 

参考资料

Spring-boot:5分钟整合Dubbo构建分布式服务

https://www.cnblogs.com/jaycekon/p/SpringBootDubbo.html

springboot+mybatis+dubbo+redis简单整合

https://blog.csdn.net/biubiuly/article/details/82776585

spring boot + Dubbo + Redis注册中心 实现RPC调用

https://blog.csdn.net/weixin_42517093/article/details/87913499

SpringBoot+dubbo 注解方式实现入门

https://blog.csdn.net/summerZBH123/article/details/82494511

dubbo整合使用有密码的redis作注册中心,并且使用指定的redis库

https://blog.csdn.net/qq_22239675/article/details/80757488

阿里云部署redis服务器,以及远程访问

https://blog.csdn.net/lwjdear/article/details/77771681

6.记录安装dubbo2.6.0的admin控制台

https://blog.csdn.net/u010316188/article/details/82785555

Dubbo后台管理和监控中心部署

https://blog.csdn.net/notonlyrush/article/details/80296358

猜你喜欢

转载自blog.csdn.net/FansUnion/article/details/89288090
今日推荐