Java从单体到微服务打造房产销售平台

概述

最近在学习某课的《Java从单体到微服务打造房产销售平台》,也算是我学习的第一门微服务课程,在此开贴记录一下知识点,如有不当请多指教!

Spring Mail发送激活链接

功能实现:在注册用户时通过spring mail发送激活链接到用户的邮箱,在有效期内用户点击链接后更新用户状态为激活状态。

引入spring-mail依赖

<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-mail</artifactId>
 </dependency>

配置appliacation.properties文件

#用来发送邮件
domain.name=127.0.0.1:8090
#spring-mail
spring.mail.host=smtp.163.com  #163邮箱
spring.mail.username=chenwuguii@163.com 
spring.mail.password=czy123456  #163邮箱授权码
spring.mail.properties.mail.smtp.auth=truehouse
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true

MailService

@Service
public class MailService {

    @Autowired
    private JavaMailSender mailSender;

    @Value("${spring.mail.username}")
    private String from;


    @Value("${domain.name}")
    private String domainName;

    @Autowired
    private UserMapper userMapper;

    //缓存key-email键值对,当超过15分钟有效期后,若用户还未激活则从数据库删除用户信息
    private final Cache<String, String> registerCache =
            CacheBuilder.newBuilder().maximumSize(100).expireAfterAccess(15, TimeUnit.MINUTES)
                    .removalListener(new RemovalListener<String, String>() {

                        @Override
                        public void onRemoval(RemovalNotification<String, String> notification) {
                            String email = notification.getValue();
                            User user = new User();
                            user.setEmail(email);
                            List<User> targetUser = userMapper.selectUsersByQuery(user);
                            if (!targetUser.isEmpty() && Objects.equal(targetUser.get(0).getEnable(), 0)) {
                                userMapper.delete(email);// 代码优化: 在删除前首先判断用户是否已经被激活,对于未激活的用户进行移除操作
                            }
                        }
                    }).build();


    /**
     * 发送邮件
     */
    @Async
    public void sendMail(String title, String url, String email) {
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom(from);//发送方邮箱
        message.setSubject(title);//标题
        message.setTo(email);//接收方邮箱
        message.setText(url);//内容
        mailSender.send(message);
    }

    /**
     * 1.缓存key-email的关系
     * 2.借助spring mail 发送邮件
     * 3.借助异步框架进行异步操作
     *
     * @param email
     */
    @Async
    public void registerNotify(String email) {
        String randomKey = RandomStringUtils.randomAlphabetic(10);
        registerCache.put(randomKey, email);
        String url = "http://" + domainName + "/accounts/verify?key=" + randomKey;
        //发送邮件
        sendMail("房产平台激活邮件", url, email);
    }
}

Nginx代理

前提:当用户上传图片时,我们在数据库存放的是相对地址,然后保存图片到本地,在浏览器需要展示图片时我们取出相对路径后拼接上前缀路径,这里我们使用nginx代理我们图片的存放位置

配置application.properties文件

#本地存放的文件路径,对应nginx.conf里alias对应目录(D:\user\images)
file.path=/user/images/
#静态资源地址前缀(若本地安装了nginx服务器,开启如下配置)
file.prefix=http://127.0.0.1:8081/images

配置nginx.conf文件

 server {
        listen       8081;//监听8081端口
        server_name  localhost;
        charset utf-8;
        //代理   
        location /images {
            alias /user/images/;
            expires 1d;
        }

这样配置的话,当nginx监听到http://localhost:8081/images的路径时,会代理到http://lcoalhost:8081/user/images下,也就是D:\user\images目录下去寻找图片。

Redis存储热点数据

在展示房源信息时我们需要显示热点房源,这里我们使用redis的有序集合实现热门房源的存储,用户查看房源详情在redis对热度加1

Redis Zincrby 命令对有序集合中指定成员的分数加上增量 increment
Redis Zremrangebyrank 命令用于移除有序集中,指定排名(rank)区间内的所有成员。
Redis Zrevrange 命令返回有序集中,指定区间内的成员。其中成员的位置按分数值递减(从大到小)来排列

RecommendService

@Service
public class RecommendService {

    private static final String HOT_HOUSE_KEY = "hot_house";

    @Autowired
    private HouseService houseService;

    /**
     * 房产热度+1
     * 原理:在redis创建有序集合存放热点房产id
     */
    public void increase(Long id) {
        try {
            Jedis jedis = new Jedis("127.0.0.1");
            jedis.auth("123");
            //对redis有序集合中指定id的分数加上1
            jedis.zincrby(HOT_HOUSE_KEY, 1.0D, id + "");
            //0代表第一个元素,-1代表最后一个元素,因为要保留热度最高的10位,所以删除第1位到倒数第11位的元素,剩下10位热度最高的
            jedis.zremrangeByRank(HOT_HOUSE_KEY, 0, -11);
            jedis.close();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }

    }

    //返回热点房产id
    public List<Long> getHot() {
        try {
            Jedis jedis = new Jedis("127.0.0.1");
            jedis.auth("123");
            //按从高到低排序取出所有元素  z + reverse + range
            Set<String> idSet = jedis.zrevrange(HOT_HOUSE_KEY, 0, -1);
            jedis.close();
            //Set<String>转换成List<Long>
            List<Long> ids = idSet.stream().map(Long::parseLong).collect(Collectors.toList());
            return ids;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return Lists.newArrayList();
        }

    }

    /**
     * 获取热点房产
     */
    public List<House> getHotHouse(Integer size) {//size为需要显示的热点房产数
        House query = new House();
        //获取热点房产id集合
        List<Long> list = getHot();
        list = list.subList(0, Math.min(list.size(), size));
        if (list.isEmpty()) {
            return Lists.newArrayList();
        }
        query.setIds(list);
        final List<Long> order = list;
        //根据id集合查询房产集合
        List<House> houses = houseService.queryAndSetImg(query, PageParams.build(size, 1));
        //因为上面会打乱顺序,所以使用Ordering类让houses根据在order中的id顺序重新进行排序
        Ordering<House> houseSort = Ordering.natural().onResultOf(hs -> order.indexOf(hs.getId()));
        return houseSort.sortedCopy(houses);
    }
    原文作者:陈污龟
    原文地址: https://segmentfault.com/a/1190000020590271
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞