最近决定搭建的自己的技术中台,之前想短平快,只用本地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构建分布式服务
springboot+mybatis+dubbo+redis简单整合
spring boot + Dubbo + Redis注册中心 实现RPC调用
SpringBoot+dubbo 注解方式实现入门
dubbo整合使用有密码的redis作注册中心,并且使用指定的redis库
阿里云部署redis服务器,以及远程访问
6.记录安装dubbo2.6.0的admin控制台
Dubbo后台管理和监控中心部署