环境
- jdk1.8
- IDEA 2018.1 for mac
- Redis 3.2.12
- EDAS轻量配置中心(本地开发把hosts改成127.0.0.1)
- Maven 中配置 EDAS 的私服地址(下不了jar包的可能是IDEA使用的和MAVEN使用的配置文件不是同一个)
- 代码:https://github.com/MYuexx/hsfdemo
一、搭建HSF框架
新建一个普通maven项目作为父项目
然后新建moudle作为生产者,这里直接新建spring项目会比较方便,这里阿里官网文档里的HSF版本不支持太高的boot版本,所以要选低版本
添加HSF依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hsf</artifactId>
<version>1.3</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-pandora</artifactId>
<version>1.3</version>
</dependency>
创建接口
public interface EchoService {
String echo(String string);
}
实现接口
import com.alibaba.boot.hsf.annotation.HSFProvider;
import com.example.redis.RedisUtil;
@HSFProvider(serviceInterface = EchoService.class)
public class EchoServiceImpl implements EchoService{
@Override
public String echo(String string) {
return "hello "+string;
}
}
启动类
import com.taobao.pandora.boot.PandoraBootstrap;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ScHsfProviderApplication {
public static void main(String[] args) {
// 启动 Pandora Boot 用于加载 Pandora 容器
PandoraBootstrap.run(args);
SpringApplication.run(ScHsfProviderApplication.class, args);
// 标记服务启动完成,并设置线程 wait。防止业务代码运行完毕退出后,导致容器退出。
PandoraBootstrap.markStartupAndWait();
}
}
application.properties配置文件
spring.application.name=hsf-provider
server.port=18081
#统一管理服务版本
spring.hsf.version=1.0.0
spring.hsf.timeout=3000
启动ScHsfProviderApplication
,这里要保证EDAS服务打开了,否则会报错,如果启动不了,可能是权限不够,在命令前加sudo
。如果启动报错hostName is null
,在启动参数里添加-Dhsf.server.ip=你的IP。这里的IP是指你网络里的IP,一般是192.168.xx.xx这种的。
打开http://localhost:8080/#/dsConfig可以看到刚刚发布的服务
再新建一个moudle作为消费者,依赖与生产者一样,把接口类复制过来,包名也要一样
public interface EchoService {
String echo(String string);
}
新建HSF配置类,所有服务都要在此配置
import com.alibaba.boot.hsf.annotation.HSFConsumer;
import org.springframework.context.annotation.Configuration;
@Configuration
public class HsfConfig {
@HSFConsumer
private EchoService echoService;
}
启动类与生产者一样
import com.taobao.pandora.boot.PandoraBootstrap;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ScHsfConsumerApplication {
public static void main(String[] args) {
PandoraBootstrap.run(args);
SpringApplication.run(ScHsfConsumerApplication.class, args);
PandoraBootstrap.markStartupAndWait();
}
}
application.properties
配置文件
spring.application.name=hsf-consumer
#端口要与生产者不同
server.port=18082
#版本号要一样
spring.hsf.version=1.0.0
spring.hsf.timeout=1000
新建Controller类测试,这里的echoService
IDEA会飘红,不用管
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class SimpleController {
@Autowired
private EchoService echoService;
@RequestMapping(value = "/hsf-echo/{str}", method = RequestMethod.GET)
public String echo(@PathVariable String str) {
return echoService.echo(str);
}
}
启动ScHsfConsumerApplication
,这时候在配置中心也能看到消费者了,访问http://localhost:18082/hsf-echo/my
搭建成功。
集成redis
启动redis服务
添加redis依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
修改application.yml
,使用application.properties
也行,只是风格不一样,两个可以共存,默认reids是没有密码的
spring:
redis:
host: 127.0.0.1
port: 6379
password:
timeout: 0
pool:
max-active: 8
max-idle: 8
max-wait: 10000
RedisConfig.java
配置类
import java.lang.reflect.Method;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
/**
* 生成key的策略
*
* @return
*/
@Bean
public KeyGenerator keyGenerator() {
return new KeyGenerator() {
@Override
public Object generate(Object target, Method method, Object... params) {
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append(method.getName());
for (Object obj : params) {
sb.append(obj.toString());
}
return sb.toString();
}
};
}
/**
* 管理缓存
*/
@Bean
public CacheManager cacheManager(RedisTemplate redisTemplate) {
RedisCacheManager rcm = new RedisCacheManager(redisTemplate);
return rcm;
}
/**
* RedisTemplate配置
*/
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
StringRedisTemplate template = new StringRedisTemplate(factory);
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);
template.afterPropertiesSet();
return template;
}
}
RedisUtil.java
工具类
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;
@Service
public class RedisUtil {
@Autowired
private RedisTemplate redisTemplate;
/**
* 写入缓存
*
* @param key
* @param value
* @return
*/
public boolean set(final String key, Object value) {
boolean result = false;
try {
ValueOperations operations = redisTemplate.opsForValue();
operations.set(key, value);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 写入缓存设置时效时间
*
* @param key
* @param value
* @return
*/
public boolean set(final String key, Object value, Long expireTime) {
boolean result = false;
try {
ValueOperations operations = redisTemplate.opsForValue();
operations.set(key, value);
redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 批量删除对应的value
*
* @param keys
*/
public void remove(final String... keys) {
for (String key : keys) {
remove(key);
}
}
/**
* 批量删除key
*
* @param pattern
*/
public void removePattern(final String pattern) {
Set keys = redisTemplate.keys(pattern);
if (keys.size() > 0)
redisTemplate.delete(keys);
}
/**
* 删除对应的value
*
* @param key
*/
public void remove(final String key) {
if (exists(key)) {
redisTemplate.delete(key);
}
}
/**
* 判断缓存中是否有对应的value
*
* @param key
* @return
*/
public boolean exists(final String key) {
return redisTemplate.hasKey(key);
}
/**
* 读取缓存
*
* @param key
* @return
*/
public Object get(final String key) {
ValueOperations operations = redisTemplate.opsForValue();
return operations.get(key);
}
/**
* 哈希 添加
*
* @param key
* @param hashKey
* @param value
*/
public void hmSet(String key, Object hashKey, Object value) {
HashOperations hash = redisTemplate.opsForHash();
hash.put(key, hashKey, value);
}
/**
* 哈希获取数据
*
* @param key
* @param hashKey
* @return
*/
public Object hmGet(String key, Object hashKey) {
HashOperations hash = redisTemplate.opsForHash();
return hash.get(key, hashKey);
}
/**
* 列表添加
*
* @param k
* @param v
*/
public void lPush(String k, Object v) {
ListOperations list = redisTemplate.opsForList();
list.rightPush(k, v);
}
/**
* 列表获取
*
* @param k
* @param l
* @param l1
* @return
*/
public List lRange(String k, long l, long l1) {
ListOperations list = redisTemplate.opsForList();
return list.range(k, l, l1);
}
/**
* 集合添加
*
* @param key
* @param value
*/
public void add(String key, Object value) {
SetOperations set = redisTemplate.opsForSet();
set.add(key, value);
}
/**
* 集合获取
*
* @param key
* @return
*/
public Set setMembers(String key) {
SetOperations set = redisTemplate.opsForSet();
return set.members(key);
}
/**
* 有序集合添加
*
* @param key
* @param value
* @param scoure
*/
public void zAdd(String key, Object value, double scoure) {
ZSetOperations zset = redisTemplate.opsForZSet();
zset.add(key, value, scoure);
}
/**
* 有序集合获取
*
* @param key
* @param scoure
* @param scoure1
* @return
*/
public Set rangeByScore(String key, double scoure, double scoure1) {
ZSetOperations zset = redisTemplate.opsForZSet();
return zset.rangeByScore(key, scoure, scoure1);
}
}
修改EchoServiceImpl.java
import com.alibaba.boot.hsf.annotation.HSFProvider;
import com.example.redis.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
@HSFProvider(serviceInterface = EchoService.class)
public class EchoServiceImpl implements EchoService{
@Autowired
private RedisUtil redisUtil;
@Override
public String echo(String string) {
redisUtil.set("hi",string);
return "hello "+string;
}
}
重启生产者,消费者不用改动,重新访问http://localhost:18082/hsf-echo/my
查询redis库
集成成功。
集成mybatis
添加依赖
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.1.1</version>
</dependency>
添加配置application.properties
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.max-idle=10
spring.datasource.max-wait=10000
spring.datasource.min-idle=5
spring.datasource.initial-size=5
#路径为你存mybatis的xml配置的路径
mybatis.mapperLocations=classpath:com/example/dao/mapper/*.xml
具体类和xml我就不放了,上一个路径图好了,我是通过工具直接生成的
修改EchoServiceImpl.java
import com.alibaba.boot.hsf.annotation.HSFProvider;
import com.example.dao.User;
import com.example.dao.UserMapper;
import com.example.redis.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
@HSFProvider(serviceInterface = EchoService.class)
public class EchoServiceImpl implements EchoService{
@Autowired
private RedisUtil redisUtil;
@Autowired
private UserMapper userMapper;
@Override
public String echo(String string) {
User user = userMapper.selectByPrimaryKey(1);
redisUtil.set("my",user);
User user1 = (User) redisUtil.get("my");
System.out.println(user1.getCname());
return "hello "+string;
}
}
重启生产者,消费者不用动,继续访问http://localhost:18082/hsf-echo/my,后台打印
查询redis
整合完毕。
整合Rabbit
自行安装erlang。由于RabbitMQ是基于erlang开发的,所以要安装RabbitMQ先必须安装erlang
安装RabbitMQ并启动RabbitMQ
添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
添加配置
mq.rabbit.host=127.0.0.1
mq.rabbit.port=5672
mq.rabbit.virtualHost=/
mq.rabbit.username=guest
mq.rabbit.password=guest
新增配置类RabbitConfig
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitConfig {
@Bean
public Queue Queue() {
return new Queue("hello");
}
}
接收消息类,这里休眠和打印时间是为了确认消息的异步性。
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component
@RabbitListener(queues = "hello")
public class HelloReceiver {
@RabbitHandler
public void process(String hello) {
try {
new Thread().sleep(2000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("消息接受为:"+hello+"------"+new Date());
}
}
修改EchoServiceImpl
import com.alibaba.boot.hsf.annotation.HSFProvider;
import com.example.dao.User;
import com.example.dao.UserMapper;
import com.example.redis.RedisUtil;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Date;
@HSFProvider(serviceInterface = EchoService.class)
public class EchoServiceImpl implements EchoService{
@Autowired
private RedisUtil redisUtil;
@Autowired
private UserMapper userMapper;
@Autowired
private AmqpTemplate amqpTemplate;
@Override
public String echo(String string) {
User user = userMapper.selectByPrimaryKey(1);
redisUtil.set("my",user);
User user1 = (User) redisUtil.get("my");
System.out.println(user1.getCname());
amqpTemplate.convertAndSend("hello", "hello rabbitMQ");
System.out.println(new Date());
return "hello "+string;
}
}
重启生产者,消费者还是不用动。访问http://localhost:18082/hsf-echo/my
整合完毕。