ํ๋ก์ ํธ๋ฅผ ์๋ ์์ด ๋ฆฌํฉํ ๋งํ๋ค.
๋ณด๋ค ๋ ๊ฐ์ฒด์งํฅ์ ์ธ ์ฝ๋๋ฅผ ์์ฑํ๊ธฐ ์ํ,
์ ์ง ๋ณด์๊ฐ ์ฌ์ด ์ฝ๋๋ฅผ ์์ฑํ๊ธฐ ์ํ,
๋ ์์ ๊ฐ์ฒด๋ฅผ ์ํ ์ฝ๋๋ฅผ ๊ณ์ํด์ ๊ณ ๋ฏผํ๊ณ ๊ตฌ์กฐ๋ฅผ ๋ณ๊ฒฝํ๋ค.
์ง๋ ๋ฌ๋ถํฐ ํด์ ์ํํธ ์จ์ด ์ํคํ
์ฒ์ ๊ดํด์ ๊ด์ฌ์ด ์๊ฒผ๋ค.
ํด๋ฆฐ ์ฝ๋๋ฅผ ์ถ๊ตฌํ๋ค ๋ณด๋ ์์ฐ์ค๋ฝ๊ฒ ์ค๊ณ์ ๊ณ ๋ฏผ์ผ๋ก ๊ท๊ฒฐ๋์๋ค.
์ํฐ๋ ๋ฐฑ์๋ ์ฑ๋ฆฐ์ง๋ฅผ ํ๋ฉฐ ์๊ฒ๋ ํด๋ฆฐ ์ํคํ
์ฒ,
๋๋ฉ์ธ ์ฃผ๋ ์ค๊ณ ์ฒ ์ ์
๋ฌธ,
๋๋ฉ์ธ ์ฃผ๋ ์ค๊ณ๋ก ์์ํ๋ ๋ง์ดํฌ๋ก ์๋น์ค๋ฅผ ์ฝ์ด๊ฐ๋ฉฐ,
๋ด๊ฐ ๊ตฌ์ฑํด์ค๋ ์ํํธ์จ์ด ์ค๊ณ์ ํฐ ์ ํ์ ์ ๋ง์ดํ๊ฒ ๋์๋ค.
๋จ์ํ ์์ ํ๋ก์ ํธ๋ง์ ๋ง๋๋๊ฒ ์๋ ๋ณธ ํ๋ก์ ํธ์ ์ด๋ฅผ ์ ์ฉ์์ผ๋ณด๊ธฐ๋ก ๊ฒฐ์ ํ๋ค.
MSA ๋ ์ค๋ฒ ์์ง๋์ด๋ง์ด๋ผ ํ๋จํ๊ณ , ๋ชจ๋
ธ๋ฆฌ์ค ๊ตฌ์กฐ์ด์ง๋ง ์ต๋ํ ๋๋ฉ์ธ ๋ณ ๋ถ๋ฆฌ๊ฐ ๋ ์์ ๋ฐ์ด๋๋ ์ปจํ
์คํธ๋ก ๋๋์ด ๋ฆฌํฉํ ๋งํ๋ค.
๊ธฐ์กด ์ฝ๋ ๊ตฌ์ฑ
๋ฐ์ด๋๋ ์ปจํ ์คํธ๋ฅผ ๋๋๊ธฐ
๊ธฐ์กด ๊ตฌ์กฐ์๋ domain ์ด๋ ์ต์์ ๊ตฌ์กฐ ์๋ ๋๋ฉ์ธ ์ปจํ
์ค๋ค์ด ์กด์ฌํจ.
์ด๋ฅผ ๋ฐ๊นฅ์ผ๋ก ๋นผ์ ํ๋์ ๋๋ฉ์ธ ๋ฐ์ด๋๋ ์ปจํ
์คํธ๋ก ๋ง๋ค์๋ค.
- global ํจํค์ง๋ ๊ฐ ์ปจํ ์คํธ๊ฐ ์ ์ญ์ ๊ณต์
- ๋๋จธ์ง ํจํค์ง๋ ๋๋ฉ์ธ ์ค์ฌ ๋ฐ์ด๋๋ ์ปจํ ์คํธ๋ก ์ค๊ณ
์ฐจ์์ ๊ตฌ์กฐ - User
- user ํจํค์ง
- ์ด๋ํฐ in out ๊ตฌ์ฑ
- ์ ํ๋ฆฌ์ผ์ด์ - usecase์ ๊ตฌํ์ฒด port service ๊ตฌ์ฑ
- ๋๋ฉ์ธ ์ํฐํฐ๋ jpa ์ํฐํฐ๋ก ๊ตฌ์ฑ
- dto ๋ชจ๋ธ์ ์ ์ญ์ ์ด๋ฏ๋ก ๊ฐ ๊ณ์ธต ๊ฐ ๊ณต์
์ธ๋ถ ๊ตฌ์กฐ - User
- ๋๋ต์ ์ธ๋ถ ๊ตฌ์กฐ ์์
๋๋ฉ์ธ ์ํฐํฐ ๋ชจ๋ธ - User
@Table(name = "users")
@Entity
@Getter
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public class User extends BaseTimeEntity<User> {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, unique = true)
private String loginId;
private String password;
private String salt;
private String name;
@Column(unique = true)
private String email;
private String address;
private String zipcode;
@Enumerated(EnumType.STRING)
private Role role;
// <๋น์ฆ๋์ค ๋ก์ง ๋ฉ์๋> //
public void updateUserInfo(final User modifiableEntity, final String updatePassword) {
this.name = modifiableEntity.getName();
this.email = modifiableEntity.getEmail();
this.address = modifiableEntity.getAddress();
this.zipcode = modifiableEntity.getZipcode();
this.password = updatePassword;
}
public void remove() {
this.role = Role.ROLE_WITHDRAWAL;
this.delete();
}
}
- Jpa entitiy๋ก ๋๋ฉ์ธ ์ํฐํฐ ๋ชจ๋ธ์ ์ฌ์ฉ
- ๊ธฐ์กด ์ฐ๊ด ๊ด๊ณ ์ญ์ (order์ ์ฐ๊ด ๊ด๊ณ ์๋ค.)
์ด๋ ๊ฒ User domain bounded context๋ฅผ ๊ฐ๋จํ ์ดํด๋ณด์๋ค.
๊ณ ๋ฏผํด ๋ณผ ๋ถ๋ถ
- ๋๋ฉ์ธ์ด ๋ถ๋ฆฌ ๋์ด ์์ด๋ ํธ๋์ญ์ ์ ์ฐ๊ฒฐ ์ง์ด์ผ ํ๋ค.
์ฒซ๋ฒ ์งธ ๋ฐฉ์
- Kafka ์ ๊ฐ์ ๋ฉ์์ง ๋ธ๋ก์ปค๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ์ค๋ฒ ์์ง๋์ด๋ง์ด๋ผ ํ๋จ.
- Spring์ด ์ ๊ณตํ๋ ๋๊ธฐ ํธ์ถ ํด๋ผ์ด์ธํธ Feign์ ์ฌ์ฉ
- MSA ๋ก ์ ํํ ๊ฒฝ์ฐ ์ข์ ์ ํ์ง๊ฐ ๋ ๊ฒ์ด๋ผ ์๊ฐํ์๋ค.
๋๋ฒ ์งธ ๋ฐฉ์
- Application Event Publisher๋ฅผ ์ฌ์ฉ
- ๋ชจ๋ ธ๋ฆฌ์ค ๊ตฌ์ฑ์์ ๋ฉ์์ง ๋ธ๋ก์ปค๋ฅผ ๊ฐ๋จํ ๊ตฌ์ฑํ๋ ๋ฐฉ๋ฒ์ด๋ผ ํ๋จํ๋ค.
๋๋ ํ์๋ฅผ ํํ๋ค.
Feign ์ ์ฌ์ฉํ๋ ๊ฒ ์กฐ์ฐจ ์ค๋ฒ ์์ง๋์ด๋ง์ด๋ผ ์๊ฐํ๋ค.
๋ฌด์๋ณด๋ค MSA๋ก ์ ํํ ์๊ฐ์ด ์์๊ธฐ์, ๊ตณ์ด API ๋๊ธฐ ํธ์ถ์ ํ ํ์๊ฐ ์๋ค.
Application Event
๋ค๋ฅธ ๋๋ฉ์ธ ์ปจํ
์คํธ์ด์ง๋ง ๊ฐ์ ํธ๋์ญ์
๋จ์๋ก ๋ฌถ์ฌ์ผ ํ๋ ํ๋ก์ธ์ค
์ด ๊ฒ์ ๋๊ธฐ ์ด๋ฒคํธ๋ก ํด๊ฒฐํจ.
eventPublisher.publishEvent(
eventBuilder.createEvent(new OrderVariation(
savedPayment.getOrderId(),
paymentId,
false))
);
eventPublisher.publishEvent(
eventBuilder.createEvent(ItemsVariation.builder()
.numbers(itemNumbers.stream().map(Long::valueOf).toList())
.quantities(itemQuantities.stream().map(Integer::valueOf).toList())
.totalAmount(response.getAmount().getTotal())
.status(false)
.build())
);
- ๊ฒฐ์ ์ทจ์๋ฅผ ํ์ ๊ฒฝ์ฐ์ด๋ค.
- Order ๋๋ฉ์ธ, Product ๋๋ฉ์ธ์ ๋ณ๋์ ์ปจํ ์คํธ์ด๋ค.
- ์ฃผ๋ฌธ ์ํ ๋ณ๊ฒฝ๊ณผ ์ํ ์๋ ๋ณ๊ฒฝ์ ๋ํ ์ด๋ฒคํธ๋ฅผ ๋ฐํํ๋ค.
- ๋น์ฐํ ํด๋น ๋ฉ์๋๋ @Transactional์ ๋ถ์ฌ ํ๋์ ํธ๋์ญ์ ์ผ๋ก ๊ฐ์ธ์ง๋ค.
- event ๋ ๋ฐ์ผ๋ก ๋๊ฐ๋ ๊ตฌ์ฑ์ด๋ฏ๋ก out ํจํค์ง์ ์์น
- order ๋๋ฉ์ธ์์ ์ด๋ฒคํธ ๊ตฌ๋ ์๋ ๋ฐ์์ ์์ผ๋ก ๋ค์ด์ค๋ ๊ตฌ์ฑ์ผ๋ก in ์ ์์น
@EventListener
public void doOrderEvent(EventModel eventModel) {
String eventAction = eventModel.getEventAction()
.orElseThrow(EventNotExistsException::new);
if (eventAction.equals(ORDER_EVENT)) {
String payload = eventModel.getPayload();
.....
=> ์ด๋ฐ ์์ผ๋ก ๋๊ธฐ๋ฐฉ์์ผ๋ก ์ด๋ฒคํธ ๊ฐ์ฒด๋ฅผ ์ฝ์ด ์คํ
=> ๋๊ธฐ ์คํ
@Column(name = "user_id", nullable = false)
private Long userId;
@Column(name = "payment_id")
private Long paymentId;
- Order ์ํฐํฐ ๋ชจ๋ธ
- ๊ธฐ์กด ์ฐ๊ด๊ด๊ณ๋ ์ง์ jpa entity ๋งคํ
- ์ง๊ธ์ pk๋ง ์ปฌ๋ผ์ผ๋ก ๊ฐ์ง๋ ๊ตฌ์ฑ
- ์ด pk๋ฅผ ๊ฐ์ง๊ณ ๋ค๋ฅธ ๋๋ฉ์ธ ์ปจํ ์คํธ์ api ์์ฒญ ๊ฐ๋ฅ
์ด๋ฐ์์ผ๋ก ๋ฆฌํฉํ ๋ง์ ํด๋ณด์๋ค.
๋์ค์ MSA๋ฅผ ์ค๊ณํ ๊ตฌ์ฑ์ ํ๋ก์ ํธ๋ฅผ ์งํํ ๊ฒฝ์ฐ
๋ฉ์์ง ๋ธ๋ก์ปค๋ ํธ๋์ญ์
๋จ์๋ฅผ ์งํค๊ธฐ ์ํ ๋ค์ํ ํจํด๋ค์ ์ ์ฉํ ์ด์์ ๋ง๋ จํ ๊ฒ ๊ฐ๋ค.
์ด๋์ ๋ ๊ฐ์ ์ก์๋ค๋ ๋ง์ด๋ค!
์ด๋ ๊ฒ ์ก์๋๊ฐ๋ฉด ๊ทธ ๋งํผ ๋ด ์ค๋ ฅ์ด ๋๋ค๊ณ ๋ฏฟ์ต๋๋ค.
'๐ Spring Framework > Spring Project' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
OutBox Pattern ์ ํ์ฉํ ๋ฉ์ผ ์ ์ก ์๋น์ค ๊ฐ๋ฐ [At Least Once] (0) | 2023.04.20 |
---|---|
[์ด์] Pageable test ๊ด๋ จ ์๋ฌ (0) | 2022.11.23 |
[Refactor] ํจํค์ง ๊ตฌ์กฐ์ ์์กด์ฑ (2) | 2022.10.14 |
[Redisson] ํธ๋์ญ์ ๋ฌธ์ ๋ฐ์ ๋ฐ ํด๊ฒฐ (0) | 2022.10.01 |
[Redisson]์ ์ด์ฉํ ๋ถ์ฐ Lock ๊ตฌํ & ๋์์ฑ ๋ฌธ์ ํด๊ฒฐ (2) | 2022.09.27 |