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);
}
}
}
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에도 저장
public ChatRoomDto createChatRoom(ChatRoomEnroll chatRoomEnroll) {
ChatRoomDto chatRoomDto = ChatRoomDto.create(chatRoomEnroll);
opsHashChatRoom.put(CHAT_ROOMS, chatRoomDto.getRoomId(), chatRoomDto);
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);
opsListChatMessage.rightPush(message.getRoomId() + message.getRoomId(), message);
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)