一、创建工程mircosevice
整体工程结构
这里主要介绍EdgeServcie服务通过Thrift调用用户服务
Thrift在Window下安装可参考: Window下 分布式框架 thrift的安装
二、创建用户接口定义模块
1、创建用户接口定义模块 user-thrift-service-api
结构如下:
1) 创建thrift定义文件 user_service.thrift
里面定义了用户模块需要提供的接口
获得用户信息,注册用户等接口
namespace java com.example.thrift.user struct UserInfo{ 1:i32 id, 2:string username, 3:string password, 4:string realName, 5:string mobile, 6:string email } service UserService{ UserInfo getUserById(1:i32 id); UserInfo getUserByName(1:string username); void registerUser(1:UserInfo userInfo); }
2) 创建生成java的shell脚本 gen-code.sh
生成的文件路径为 工程下的src/main/java
#!/usr/bin/env bash thrift --gen java --out ../src/main/java user_service.thrift
执行shell脚本.
生成的文件如UserInfo和UserService
3) 增加依赖
<dependencies> <dependency> <groupId>org.apache.thrift</groupId> <artifactId>libthrift</artifactId> <version>0.13.0</version> </dependency> </dependencies>
三、创建用户模块(接口实现)
1、结构如下图所示
2、pom文件配置如下
springboot版本为1.5.9
增加user-thrift-service-api模块依赖
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.9.RELEASE</version> </parent> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>user-thrift-service</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.apache.thrift</groupId> <artifactId>libthrift</artifactId> <version>0.13.0</version> </dependency> <dependency> <groupId>com.example</groupId> <artifactId>user-thrift-service-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.1</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.39</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.2</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> </project>
3、application.properties 配置如下
service.name=user-thrift-server service.port=7911 #数据源配置 spring.datasource.url=jdbc:mysql://localhost:3306/db_user spring.datasource.username=root spring.datasource.password= spring.datasource.driver-class-name=com.mysql.jdbc.Driver
4、UserMapper
这里使用注解的方式操作数据库
@Mapper public interface UserMapper { @Select("select id, username,password, realName , mobile, email from user where id = #{id}") UserInfo getUserById(@Param("id") int id); @Select("select id, username,password, realName , mobile, email from user where username = #{username}") UserInfo getUserByName(@Param("username") String username); @Insert("insert into user(username,password, realName , mobile, email values(#{u.username}, #{u.password}, #{u.realName},#{u.mobile},#{u.email} )") void registerUser(@Param("u") UserInfo userInfo); }
5、接口实现类UserServiceImpl
@Service public class UserServiceImpl implements UserService.Iface { @Autowired private UserMapper userMapper; @Override public UserInfo getUserById(int id) throws TException { return userMapper.getUserById(id); } @Override public UserInfo getUserByName(String username) throws TException { return userMapper.getUserByName(username); } @Override public void registerUser(UserInfo userInfo) throws TException { userMapper.registerUser(userInfo); } }
6、启动Thrift服务
@Configuration public class ThriftServer { @Value("${service.port}") private int servicePort; @Autowired private UserService.Iface userService; //运行Thrift服务 @PostConstruct public void startThriftServer() { TProcessor processor = new UserService.Processor<>(userService); TNonblockingServerSocket socket = null; try { socket = new TNonblockingServerSocket(servicePort); } catch (TTransportException e) { e.printStackTrace(); } TNonblockingServer.Args args = new TNonblockingServer.Args(socket); args.processor(processor); //传输方式: 贞传输 args.transportFactory(new TFramedTransport.Factory()); //二进制Protocol args.protocolFactory(new TBinaryProtocol.Factory()); TServer server = new TNonblockingServer(args); server.serve(); System.out.println("启动用户Thrift服务成功"); } }
六、创建用户edge服务 user-edge-service
1、pom.xml
增加libthrift引用和user-thrift-service-api模块引用
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.9.RELEASE</version> </parent> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>user-edge-service</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.apache.thrift</groupId> <artifactId>libthrift</artifactId> <version>0.13.0</version> </dependency> <dependency> <groupId>com.example</groupId> <artifactId>user-thrift-service-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.6</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.2</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> </project>
2、application.properties
service.name=user-edge-server service.port=8082 thrift.user.ip=127.0.0.1 thrift.user.port=7911 # redis config #spring.redis.host=localhost spring.redis.port=6379 spring.redis.timeout=30000
3、redis配置如下
1)Redis配置
/** * Redis缓存配置类 */ @Configuration @EnableCaching public class RedisConfig extends CachingConfigurerSupport { @Value("${spring.redis.host}") private String host; @Value("${spring.redis.port}") private int port; @Value("${spring.redis.timeout}") private int timeout; //缓存管理器 @Bean public CacheManager cacheManager(RedisTemplate redisTemplate) { RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate); //设置缓存过期时间 cacheManager.setDefaultExpiration(10000); return cacheManager; } @Bean public JedisConnectionFactory redisConnectionFactory() { JedisConnectionFactory factory = new JedisConnectionFactory(); factory.setHostName(host); factory.setPort(port); factory.setTimeout(timeout); return factory; } @Bean public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory){ StringRedisTemplate template = new StringRedisTemplate(factory); setSerializer(template);//设置序列化工具 template.afterPropertiesSet(); return template; } private void setSerializer(StringRedisTemplate template){ 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); template.setValueSerializer(jackson2JsonRedisSerializer); } }
2) Redis客户端
@Component public class RedisClient { @Autowired private RedisTemplate redisTemplate; public <T> T get(String key) { return (T)redisTemplate.opsForValue().get(key); } public void set(String key, Object value) { redisTemplate.opsForValue().set(key, value); } public void set(String key, Object value, int timeout) { redisTemplate.opsForValue().set(key, value, timeout, TimeUnit.SECONDS); } public void expire(String key, int timeout) { redisTemplate.expire(key, timeout, TimeUnit.SECONDS); } }
4、用户服务
@Component public class UserServiceProvider { @Value("${thrift.user.ip}") private String serverIp; @Value("${thrift.user.port}") private int serverPort; public UserService.Client getUserService(){ TSocket socket = new TSocket(serverIp, serverPort,3000); TTransport transport = new TFramedTransport(socket); try { transport.open(); } catch (TTransportException e) { e.printStackTrace(); return null; } TProtocol protocol = new TBinaryProtocol(transport); UserService.Client client = new UserService.Client(protocol); return client; } }
5、用户Controller
login接口
@Controller public class UserController { @Autowired private UserServiceProvider usrServiceProvider; @Autowired private RedisClient redisClient; @RequestMapping(value = "/login", method = RequestMethod.POST) @ResponseBody public Response login(@RequestParam("username") String username, @RequestParam("password") String password){ //1、验证用户名密码 UserInfo userInfo = null; try { userInfo = usrServiceProvider.getUserService().getUserByName(username); } catch (TException e) { e.printStackTrace(); return Response.getUserNameOrPwdError(); } if(userInfo == null){ return Response.getUserNameOrPwdError(); } if(!userInfo.getPassword().equalsIgnoreCase(md5(password))){ return Response.getUserNameOrPwdError(); } //2、生成token String token = genToken(); //3. 缓存用户 redisClient.set(token, toDTO(userInfo), 3600); return new LoginResponse(token); } }
通过获得用户服务,然后调用用户服务的getUserByName方法
userInfo = usrServiceProvider.getUserService().getUserByName(username);
6、测试
通过login接口,带上用户名和密码进行测试