2023-02-07

강혜성·2023년 2월 7일
0

ZZALU 프로젝트

목록 보기
7/11

CI/CD 이슈

  • jenkins에서 자동 빌드, 배포되는 dev, be 브랜치는 각 각 다른 포트로 실행이 됨. redis는 공유하고 있음.
  • dev 브랜치가 빌드, 배포되면 redis에 저장되어 있던 정보들이 flushall 되는 현상이 발생.
  • backup1, backup2 script가 있으면서, 모든 key가 사라지는 현상은 구글링 결과 크롤링 봇에 의한 해킹이라 되어 있어서 password / auth를 추가.

채팅방 기능 추가

  • Write Through 패턴을 사용해 데이터를 저장한다.
  • 데이터를 저장할 때 Cache에 저장한 후 DB에 바로 저장
1. JPA - Redis 연동 
	1. 채팅방이 CREATE 될 때
        1. Redis에 저장
    	2. MariaDB에 저장
    
    2. 채팅 메시지가 send 될 때
        1. Redis에 저장
    	2. MariaDB에 저장

	3. 채팅방 입장 시 
    	1. Cache hit -> redis
        2. Cache miss -> Maria DB

2. 채팅방 필터링 API 추가
  1. 이름 또는 해시태그 검색
      1. 전체 
          1. 최신 대화 순
          2. 좋아요 순
      2. 내가 개설한 방
          1. 최신 대화 순
          2. 좋아요 순
      3. 즐겨찾기
          1. 최신 대화 순
          2. 좋아요 순

JPA - Redis 연동

  • 다대일 관계로 형성
  • ChatRoom Entity 생성
package com.samsamoo.zzalu.chat.entity;

import com.samsamoo.zzalu.member.entity.Member;
import lombok.*;

import javax.persistence.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;

@Entity
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ChatRoom {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "CHAT_ROOM_ID")
    private Long id;

    @Column(name = "ROOM_ID")
    private String roomId;

    @Column(name = "ROOM_NAME")
    private String roomName;

    @Column(name = "USER_NAME")
    private String userNmae;

    @Column(name = "MEMBER_ID")
    private Long memberId;

    @Column(name = "LIKE_COUNT")
    private Long likeCount;

    @OneToMany(mappedBy = "chatRoom")
    private List<ChatMessage> chatMessages  = new LinkedList<>();

    @Column(name = "LIKE_MEMBERS")
    private HashMap<Member, Boolean> likeMembers;

    @Column(name = "IMAGE_PATH")
    private String imagePath;

    @Column(name = "DESCRIPTION")
    private String description;

    @Column(name = "TAGS")
    private String tags;

    @Column(name = "ENROLL_DATE")
    private LocalDateTime enrollDate;

    @Column(name = "LAST_ACTIVATION")
    private LocalDateTime lastActivation;

    public void addChatMessage(ChatMessage chatMessage) {
        this.chatMessages.add(chatMessage);
        if(chatMessage.getChatRoom() != this) {
            chatMessage.setChatRoom(this);
        }
    }

}
  • ChatMessage Entity 생성
package com.samsamoo.zzalu.chat.entity;

import com.samsamoo.zzalu.chat.dto.ChatMessageDto;
import lombok.*;

import javax.persistence.*;
import java.time.LocalDateTime;

@Entity
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ChatMessage {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "CHAT_MESSAGE_ID")
    private Long id;

    @Column(name = "TYPE")
    private ChatMessageDto.MessageType type;

    @Column(name = "ROOM_ID")
    private String roomId;

    @Column(name = "SENDER")
    private String sender;

    @Column(name = "MESSAGE")
    private String message;

    @Column(name = "SEMD_DATE")
    private LocalDateTime sendDate;

    @ManyToOne
    @JoinColumn(name = "CHAT_ROOM_ID")
    private ChatRoom chatRoom;

    public void setChatRoom(ChatRoom chatRoom){
        if(this.chatRoom != null) {
            this.chatRoom.getChatMessages().remove(this);
        }
        this.chatRoom = chatRoom;
        if(!chatRoom.getChatMessages().contains(this)) {
            chatRoom.getChatMessages().add(this);
        }
    }

}
  • ChatRoom 정보를 Redis 저장할 경우 DB에도 저장
	/**
     * 채팅방 생성 : 서버간 채팅방 공유를 위해 redis hash에 저장한다.
     */
    public ChatRoomDto createChatRoom(ChatRoomEnroll chatRoomEnroll) {
        ChatRoomDto chatRoomDto = ChatRoomDto.create(chatRoomEnroll);
        // Redis key-value 저장
        opsHashChatRoom.put(CHAT_ROOMS, chatRoomDto.getRoomId(), chatRoomDto);
        // MariaDB JPA 저장
        chatRoomRepository.save(chatRoomDto.toEntity());
        return chatRoomDto;
    }
  • ChatMessage 정보를 Redis에 저장할 경우 DB에도 저장
@CacheEvict(value = "ChatMessages", key = "#message.getRoomId() + #message.getRoomId()", allEntries = true)
    public void setChatMessage(ChatMessageDto message) {
        LocalDateTime sendDate = LocalDateTime.now();
        message.setSendDate(sendDate);
        ChatRoomDto chatRoomDto = findRoomById(message.getRoomId());
        chatRoomDto.setLastActivation(sendDate);
        // Redis에 저장
        opsListChatMessage.rightPush(message.getRoomId() + message.getRoomId(), message);
        // DB에 저장
        ChatRoom chatRoom = chatRoomRepository.findByRoomId(chatRoomDto.getRoomId());
        if(chatRoom != null) {
            ChatMessage chatMessage = message.toEntity();
            chatMessage.setChatRoom(chatRoom);
            chatRoom.addChatMessage(chatMessage);
            chatRepository.save(chatMessage);
            chatRoomRepository.save(chatRoom);
        } else {
            System.out.println("need chat room not found exception throw");
        }
    }

채팅방 필터링 API 추가

  • 이름 또는 해시태그 검색
	List<ChatRoom> findByTagsContainsOrRoomNameContains(String keyword1, String keyword2);
    List<ChatRoom> findByTagsContains(String keyword1);
    List<ChatRoom> findByRoomNameContains(String keyword1);
  • 최신 대화 순, 좋아요 순 필터링
	List<ChatRoom> findAllByMemberId(Long memberId);
    List<ChatRoom> findAllByMemberIdOrderByLastActivationDesc(Long memberId);
    List<ChatRoom> findAllByMemberIdOrderByLikeCountDesc(Long memberId);
    List<ChatRoom> findAllByTagsContainsOrRoomNameContainsOrderByLastActivationDesc(String keyword1, String keyword2);
    List<ChatRoom> findAllByTagsContainsOrRoomNameContainsOrderByLikeCount(String keyword1, String keyword2);
    List<ChatRoom> findAllByMemberIdAndTagsContainsOrRoomNameContainsOrderByLastActivationDesc(Long memberId, String keyword1, String keyword2);
    List<ChatRoom> findAllByMemberIdAndTagsContainsOrRoomNameContainsOrderByLikeCountDesc(Long memberId, String keyword1, String keyword2);

짤 사용 통계 JPA 설계 필요

1. GIF 파일 전송 회수를 알아야 한다.
2. GIF 

채팅방 즐겨찾기 구현 필요

  • 즐겨 찾기 구현은 N:M 관계로 (Member : ChatRoom)

0개의 댓글