redis+feign负载均衡器集成微服务

1、redis集成到微服务

redis一般用来做中央缓存:
前台请求来进行访问,会先到redis里面去查询,如果redis没有,那么就会到数据库中查询,再把查询出来的数据放到redis里面,下次来访问的时候就会到redis里面去查询

1.1导包

<dependencies>
   <!--注册中心客户端包-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <!--  集成Web的jar包,客户端必须要加-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <!--redis-->
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>3.2.0</version>
    </dependency>
</dependencies>

1.2 集成Jedis操作Redis

jedis里面包含set key 和get key的方法
注意:直接把他抽成一个工具类(RedisUtils),方便直接使用

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.io.IOException;
import java.util.Properties;

/**
 * 获取连接池对象
 */
public enum RedisUtils {
    INSTANCE;
    static JedisPool jedisPool = null;

    static {
        //1 创建连接池配置对象
        JedisPoolConfig config = new JedisPoolConfig();
        //2 进行配置-四个配置
        config.setMaxIdle(1);//最小连接数
        config.setMaxTotal(11);//最大连接数
        config.setMaxWaitMillis(10 * 1000L);//最长等待时间
        config.setTestOnBorrow(true);//测试连接时是否畅通
        //3 通过配置对象创建连接池对象
        Properties properties = null;
        try {
            properties = new Properties();
            properties.load(RedisUtils.class.getClassLoader().getResourceAsStream("redis.properties"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        String host = properties.getProperty("redis.host");
        String port = properties.getProperty("redis.port");
        String password = properties.getProperty("redis.password");
        String timeout = properties.getProperty("redis.timeout");

        jedisPool = new JedisPool(config, host, Integer.valueOf(port),Integer.valueOf(timeout), password);
    }

    //获取连接
    public Jedis getSource() {
        return jedisPool.getResource();
    }

    //关闭资源
    public void closeSource(Jedis jedis) {
        if (jedis != null) {
            jedis.close();
        }

    }

    /**
     * 设置字符值
     *
     * @param key
     * @param value
     */
    public void set(String key, String value) {
        Jedis jedis = getSource();
        jedis.set(key, value);
        closeSource(jedis);
    }

    /**
     * 设置
     * @param key
     * @param value
     */
    public void set(byte[] key, byte[] value) {
        Jedis jedis = getSource();
        jedis.set(key, value);
        closeSource(jedis);
    }

    /**
     *
     * @param key
     * @return
     */
    public byte[]  get(byte[] key) {
        Jedis jedis = getSource();
        try {
            return jedis.get(key);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            closeSource(jedis);
        }
        return null;

    }

    /**
     * 设置字符值
     *
     * @param key
     */
    public String get(String key) {
        Jedis jedis = getSource();
        try {
            return jedis.get(key);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            closeSource(jedis);
        }

        return null;

    }
}

redis.properties (里面包含redis的密码等等…上面的工作类在使用,相当于jdbc.properties )

redis.host=127.0.0.1
redis.port=6379  #redis的端口
redis.password=123456   #redis服务端的密码
redis.timeout=10000   #超时时间10

1.3 controller

暴露一个路径(controller),为了在请求时在redis里面获取值和设置值
@RestController
@RequestMapping("/redis")
public class RedisController {

    //设置值
    @PostMapping("/set")   //@RequestParam("key"):从请求参数中去获取值要设置的值
    public AjaxResult set(@RequestParam("key")String key,@RequestParam("value")String value){
    
    	//------主要代码---------
        RedisUtils.INSTANCE.set(key,value);
		//-------------------  
        
        return AjaxResult.me();
    }

    //取值(根据key来取值)
    @GetMapping("/get/{key}")
    public AjaxResult get(@PathVariable("key")String key){
        String obj = RedisUtils.INSTANCE.get(key);
        return AjaxResult.me().setResultObj(obj); //将从redis里面获取到的数据封装到返回结果中,方便其他地方使用(也可以直接返回一个String的对象)
    }

}

2、feign集成redis

2.1导包

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

2.2 自定义一个接口

写一个接口分发请求(里面的方法,必须要和被调用的方法名一样),其他的请求就通过调用这里面的方法来找到对应的redis方法

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;

//调用目标服务名(redis这个微服务的服务名)
@FeignClient(value="redis-server") 
public interface RedisFeign {

 //localhost://redis-server//redis/set 最终就会调用到redis里面的set方法
    @PostMapping("/redis/set")   //@RequestParam("key"):从请求参数中去获取值
    AjaxResult set(@RequestParam("key")String key, @RequestParam("value")String value);


    //取值
    @GetMapping("/redis/get/{key}")
    AjaxResult get(@PathVariable("key")String key);
}

2.3 其他业务微服务通过feign来调用redis

1、还是导入上面的openfeign的包,让后在主配置类里面加入开启feign的注解

@EnableEurekaClient
@EnableFeignClients(value = "com.wz.feign")  //开启feign(后面跟feign的接口包名)
public class CourseServerApplication2010 {

    public static void main( String[] args )
    {
        SpringApplication.run(CourseServerApplication2010.class);
    }
}

2、service层里,将查询出来的数据放到redis里面

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements ICourseTypeService {

    @Autowired
    private RedisFeign redisFeign;   //注入feign接口

    /**
     *  课程分类查询
     * @return
     */
    @Override
    public List<User> treeData() {

        //先根据key到redis里面查询(存储到redis时自定义的一个key)
        AjaxResult user_type= redisFeign.get("user_type");
        
        //如果到redis里面去查询时有值的那么就直接把redis里面的数据返回给controller   (redis里的值是存在自定类的setResultObj()方法里面的)
        if(!user_type.isSuccess()||null!=user_type.getResultObj() ){
            //根据key从redis中查询到了对应的数据
            Object userObj = user_type.getResultObj();
            //将json对象转换成字符串
            //现在查询获取的就是redis里面查询的的全部数据(就可以直接返回这份数据给前台)
            List<User> userType= JSON.parseArray((String) userObj , User.class);
        }else {  //如果redis里面没有,就到数据库中查询,在把它放到redis里面
            //先查询用户的全部数据
            List<User> userList= baseMapper.selectList(null);  //这就是到数据库中去查询全部数据 : userMapper.selectAll();
            String jsonString = JSON.toJSONString(userList); //将查询出来的集合转换成字符串
            
            //将数据库中查询出来的数据放到redis里面
            redisFeign.set("user_type", jsonString);
        }

如果是增删改,需要操作完数据后在重新查询数据库中的数据,在同步到redis,否则会造成脏数据

@Override
public boolean insert(CourseType entity) {
	//这里是保存数据
     boolean insert = super.insert(entity);
	
	
	//-------------保存完成后--------------
     //先查询用户的全部数据
     List<User> userList= baseMapper.selectList(null);  //这就是到数据库中去查询全部数据 : userMapper.selectAll();
     String jsonString = JSON.toJSONString(userList); //将查询出来的集合转换成字符串
     //将数据库中查询出来的数据放到redis里面(进行数据更新)
     redisFeign.set("user_type", jsonString);


     return insert;
 }

json数据之间的相互装换导的包(之后才能用JSON这个方法来进行转换)

<!--fastjson-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.62</version>
</dependency>
发布了20 篇原创文章 · 获赞 4 · 访问量 2099

猜你喜欢

转载自blog.csdn.net/weixin_45028726/article/details/104383306