세션 클러스터링 작업중. 중간저장.
parent
ef5c022d8b
commit
a27d98eb42
|
|
@ -20,6 +20,9 @@ repositories {
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly 'org.projectlombok:lombok:1.18.24'
|
compileOnly 'org.projectlombok:lombok:1.18.24'
|
||||||
|
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor:2.7.2'
|
||||||
|
annotationProcessor 'org.projectlombok:lombok:1.18.24'
|
||||||
|
|
||||||
implementation 'org.springframework.boot:spring-boot-starter-actuator:2.7.2'
|
implementation 'org.springframework.boot:spring-boot-starter-actuator:2.7.2'
|
||||||
implementation 'org.springframework.boot:spring-boot-starter-data-jpa:2.7.2'
|
implementation 'org.springframework.boot:spring-boot-starter-data-jpa:2.7.2'
|
||||||
implementation 'org.springframework.boot:spring-boot-starter-security:2.7.2'
|
implementation 'org.springframework.boot:spring-boot-starter-security:2.7.2'
|
||||||
|
|
@ -31,6 +34,7 @@ dependencies {
|
||||||
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5:3.0.4.RELEASE'
|
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5:3.0.4.RELEASE'
|
||||||
|
|
||||||
developmentOnly 'org.springframework.boot:spring-boot-devtools:2.7.2'
|
developmentOnly 'org.springframework.boot:spring-boot-devtools:2.7.2'
|
||||||
|
implementation 'org.apache.tomcat:tomcat-catalina-ha:9.0.62'
|
||||||
|
|
||||||
implementation 'org.bgee.log4jdbc-log4j2:log4jdbc-log4j2-jdbc4.1:1.16'
|
implementation 'org.bgee.log4jdbc-log4j2:log4jdbc-log4j2-jdbc4.1:1.16'
|
||||||
runtimeOnly 'org.postgresql:postgresql:42.3.6'
|
runtimeOnly 'org.postgresql:postgresql:42.3.6'
|
||||||
|
|
@ -44,9 +48,6 @@ dependencies {
|
||||||
implementation 'org.apache.poi:poi:4.1.0'
|
implementation 'org.apache.poi:poi:4.1.0'
|
||||||
implementation 'org.apache.poi:poi-ooxml:4.1.0'
|
implementation 'org.apache.poi:poi-ooxml:4.1.0'
|
||||||
|
|
||||||
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor:2.7.2'
|
|
||||||
annotationProcessor 'org.projectlombok:lombok:1.18.24'
|
|
||||||
|
|
||||||
//crossEditor 요구 라이브러리
|
//crossEditor 요구 라이브러리
|
||||||
//implementation files('libs/commons-codec-1.15.jar') // 이미 추가되어 있어서 제외.
|
//implementation files('libs/commons-codec-1.15.jar') // 이미 추가되어 있어서 제외.
|
||||||
implementation files('libs/commons-fileupload-1.4.jar')
|
implementation files('libs/commons-fileupload-1.4.jar')
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
package com.dbnt.faisp.config.tomcat;
|
package com.dbnt.faisp.config.tomcat;
|
||||||
|
|
||||||
import org.apache.catalina.connector.Connector;
|
import org.apache.catalina.connector.Connector;
|
||||||
import org.apache.coyote.ProtocolHandler;
|
|
||||||
import org.apache.coyote.ajp.AbstractAjpProtocol;
|
import org.apache.coyote.ajp.AbstractAjpProtocol;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
|
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
|
||||||
|
|
@ -9,10 +8,8 @@ import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
import java.net.InetAddress;
|
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
public class TomcatConfiguration {
|
public class TomcatAjpConfiguration {
|
||||||
|
|
||||||
@Value("${tomcat.ajp.protocol}")
|
@Value("${tomcat.ajp.protocol}")
|
||||||
private String protocol;
|
private String protocol;
|
||||||
|
|
@ -0,0 +1,94 @@
|
||||||
|
package com.dbnt.faisp.config.tomcat;
|
||||||
|
|
||||||
|
import org.apache.catalina.Context;
|
||||||
|
import org.apache.catalina.Engine;
|
||||||
|
import org.apache.catalina.ha.session.ClusterSessionListener;
|
||||||
|
import org.apache.catalina.ha.session.DeltaManager;
|
||||||
|
import org.apache.catalina.ha.session.JvmRouteBinderValve;
|
||||||
|
import org.apache.catalina.ha.tcp.ReplicationValve;
|
||||||
|
import org.apache.catalina.ha.tcp.SimpleTcpCluster;
|
||||||
|
import org.apache.catalina.tribes.group.GroupChannel;
|
||||||
|
import org.apache.catalina.tribes.group.interceptors.MessageDispatchInterceptor;
|
||||||
|
import org.apache.catalina.tribes.group.interceptors.StaticMembershipInterceptor;
|
||||||
|
import org.apache.catalina.tribes.group.interceptors.TcpFailureDetector;
|
||||||
|
import org.apache.catalina.tribes.group.interceptors.TcpPingInterceptor;
|
||||||
|
import org.apache.catalina.tribes.membership.McastService;
|
||||||
|
import org.apache.catalina.tribes.membership.StaticMember;
|
||||||
|
import org.apache.catalina.tribes.transport.ReplicationTransmitter;
|
||||||
|
import org.apache.catalina.tribes.transport.nio.NioReceiver;
|
||||||
|
import org.apache.catalina.tribes.transport.nio.PooledParallelSender;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class TomcatClusterContextCustomizer implements TomcatContextCustomizer {
|
||||||
|
|
||||||
|
@Value("${tomcat.cluster.static-member-host:}")
|
||||||
|
private String staticMemberHost;
|
||||||
|
@Value("${tomcat.cluster.static-member-port:}")
|
||||||
|
private Integer staticMemberPort;
|
||||||
|
@Value("${tomcat.cluster.static-member-unique-id:}")
|
||||||
|
private String staticMemberUniqueId;
|
||||||
|
@Value("${tomcat.cluster.receiver-address:}")
|
||||||
|
private String receiverAddress;
|
||||||
|
@Value("${tomcat.cluster.receiver-port:}")
|
||||||
|
private Integer receiverPort;
|
||||||
|
@Value("${tomcat.cluster.receiver-max-threads:}")
|
||||||
|
private Integer receiverMaxThreads;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void customize( final Context context ) {
|
||||||
|
context.setDistributable(true);
|
||||||
|
// BackupManager manager = new BackupManager();
|
||||||
|
DeltaManager manager = new DeltaManager();
|
||||||
|
manager.setExpireSessionsOnShutdown(false);
|
||||||
|
manager.setNotifyListenersOnReplication(true);
|
||||||
|
context.setManager(manager);
|
||||||
|
configureCluster( (Engine)context.getParent().getParent() );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void configureCluster(Engine engine) {
|
||||||
|
//cluster setting
|
||||||
|
SimpleTcpCluster cluster = new SimpleTcpCluster();
|
||||||
|
cluster.setChannelStartOptions(3);
|
||||||
|
cluster.setChannelSendOptions(8);
|
||||||
|
|
||||||
|
//channel setting
|
||||||
|
GroupChannel channel = new GroupChannel();
|
||||||
|
StaticMembershipInterceptor interceptor = new StaticMembershipInterceptor();
|
||||||
|
|
||||||
|
// 대상 정보
|
||||||
|
StaticMember staticMember = new StaticMember();
|
||||||
|
staticMember.setHost(staticMemberHost);
|
||||||
|
staticMember.setPort(staticMemberPort);
|
||||||
|
staticMember.setSecurePort(-1);
|
||||||
|
staticMember.setUniqueId(staticMemberUniqueId);
|
||||||
|
interceptor.addStaticMember(staticMember);
|
||||||
|
|
||||||
|
//receiver(현재 자신의 정보)
|
||||||
|
NioReceiver receiver = new NioReceiver();
|
||||||
|
receiver.setAddress(receiverAddress);
|
||||||
|
receiver.setPort(receiverPort);
|
||||||
|
receiver.setMaxThreads(receiverMaxThreads);
|
||||||
|
channel.setChannelReceiver(receiver);
|
||||||
|
|
||||||
|
channel.addInterceptor(interceptor);
|
||||||
|
|
||||||
|
//sender setting
|
||||||
|
ReplicationTransmitter sender = new ReplicationTransmitter();
|
||||||
|
sender.setTransport(new PooledParallelSender());
|
||||||
|
channel.setChannelSender(sender);
|
||||||
|
|
||||||
|
//interceptor setting
|
||||||
|
channel.addInterceptor(new TcpPingInterceptor());
|
||||||
|
channel.addInterceptor(new TcpFailureDetector());
|
||||||
|
channel.addInterceptor(new MessageDispatchInterceptor());
|
||||||
|
|
||||||
|
cluster.addValve(new ReplicationValve());
|
||||||
|
cluster.addValve(new JvmRouteBinderValve());
|
||||||
|
cluster.setChannel(channel);
|
||||||
|
cluster.addClusterListener(new ClusterSessionListener());
|
||||||
|
engine.setCluster(cluster);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.dbnt.faisp.config.tomcat;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
|
||||||
|
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class TomcatClusterUtil implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
|
||||||
|
private final TomcatClusterContextCustomizer tomcatClusterContextCustomizer;
|
||||||
|
|
||||||
|
@Value("${tomcat.cluster.enabled}")
|
||||||
|
private boolean clusterEnabled;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void customize( final TomcatServletWebServerFactory factory ) {
|
||||||
|
if(clusterEnabled){
|
||||||
|
factory.addContextCustomizers(tomcatClusterContextCustomizer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
tomcat.ajp.protocol=HTTP/1.1
|
|
||||||
spring.devtools.livereload.enabled=true
|
spring.devtools.livereload.enabled=true
|
||||||
|
|
||||||
|
tomcat.ajp.protocol=HTTP/1.1
|
||||||
|
tomcat.cluster.enabled=false
|
||||||
|
|
||||||
#file upload
|
#file upload
|
||||||
spring.servlet.multipart.location=C:\\faispUploadFiles
|
spring.servlet.multipart.location=C:\\faispUploadFiles
|
||||||
spring.servlet.multipart.max-file-size=200MB
|
spring.servlet.multipart.max-file-size=200MB
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,16 @@
|
||||||
|
#tomcat
|
||||||
tomcat.ajp.protocol=HTTP/1.1
|
tomcat.ajp.protocol=HTTP/1.1
|
||||||
|
|
||||||
|
logging.level.org.apache.tomcat: DEBUG
|
||||||
|
logging.level.org.apache.catalina: DEBUG
|
||||||
|
tomcat.cluster.enabled=true
|
||||||
|
tomcat.cluster.static-member-host=172.80.0.3
|
||||||
|
tomcat.cluster.static-member-port=4040
|
||||||
|
tomcat.cluster.static-member-unique-id={0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2}
|
||||||
|
tomcat.cluster.receiver-address=172.80.0.2
|
||||||
|
tomcat.cluster.receiver-port=4040
|
||||||
|
tomcat.cluster.receiver-max-threads=4
|
||||||
|
|
||||||
#file upload
|
#file upload
|
||||||
spring.servlet.multipart.location=/uploadFiles
|
spring.servlet.multipart.location=/uploadFiles
|
||||||
spring.servlet.multipart.max-file-size=200MB
|
spring.servlet.multipart.max-file-size=200MB
|
||||||
|
|
@ -0,0 +1,77 @@
|
||||||
|
#tomcat
|
||||||
|
tomcat.ajp.protocol=HTTP/1.1
|
||||||
|
|
||||||
|
logging.level.org.apache.tomcat: DEBUG
|
||||||
|
logging.level.org.apache.catalina: DEBUG
|
||||||
|
tomcat.cluster.enabled=true
|
||||||
|
tomcat.cluster.static-member-host=172.80.0.2
|
||||||
|
tomcat.cluster.static-member-port=4040
|
||||||
|
tomcat.cluster.static-member-unique-id={0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1}
|
||||||
|
tomcat.cluster.receiver-address=172.80.0.3
|
||||||
|
tomcat.cluster.receiver-port=4040
|
||||||
|
tomcat.cluster.receiver-max-threads=4
|
||||||
|
|
||||||
|
#file upload
|
||||||
|
spring.servlet.multipart.location=/uploadFiles
|
||||||
|
spring.servlet.multipart.max-file-size=200MB
|
||||||
|
spring.servlet.multipart.max-request-size=500MB
|
||||||
|
|
||||||
|
site.domain=http://118.219.150.34:50580
|
||||||
|
|
||||||
|
#file
|
||||||
|
file.dir.publicBoard=/publicBoard
|
||||||
|
file.dir.faRpt=/faRpt
|
||||||
|
file.dir.vulnerable=/vulnerable
|
||||||
|
file.dir.part=/part
|
||||||
|
file.dir.equip=/equip
|
||||||
|
file.dir.sailor=/sailor
|
||||||
|
file.dir.affair=/affair
|
||||||
|
file.dir.affair.plan=/affairPlan
|
||||||
|
file.dir.affair.result=/affairResult
|
||||||
|
file.dir.editor=/editor
|
||||||
|
file.dir.sri=/sri
|
||||||
|
file.dir.ciw=/ciw
|
||||||
|
file.dir.cia.safty=/cia/safty
|
||||||
|
file.dir.cia.company=/cia/company
|
||||||
|
file.dir.cia.foreigner=/cia/foreigner
|
||||||
|
file.dir.cia.edu=/cia/edu
|
||||||
|
file.dir.activityCase=/activityCase
|
||||||
|
file.dir.majorStatus=/majorStatus
|
||||||
|
file.dir.monitoring=/monitoring
|
||||||
|
file.dir.intelligenceNetwork=/intelligenceNetwork
|
||||||
|
|
||||||
|
file.dir.affairTemp=/affairTemp
|
||||||
|
|
||||||
|
editor.img.view=/file/editorFileDisplay?fileNm=
|
||||||
|
|
||||||
|
#thymeleaf
|
||||||
|
spring.thymeleaf.prefix=classpath:templates/
|
||||||
|
spring.thymeleaf.check-template-location=true
|
||||||
|
spring.thymeleaf.suffix=.html
|
||||||
|
spring.thymeleaf.mode=HTML
|
||||||
|
|
||||||
|
#Datasource Configuration
|
||||||
|
spring.sql.init.encoding=utf-8
|
||||||
|
#maximum-pool-size: CPU core count
|
||||||
|
spring.datasource.hikari.maximum-pool-size=4
|
||||||
|
#postgresql
|
||||||
|
spring.datasource-main.driverClassName=org.postgresql.Driver
|
||||||
|
spring.datasource-main.jdbcUrl=jdbc:postgresql://118.219.150.34:50503/faisp
|
||||||
|
spring.datasource-main.username=dbnt0031
|
||||||
|
spring.datasource-main.password=dbnt0928!
|
||||||
|
#oracle
|
||||||
|
spring.datasource-kwms.driverClassName=oracle.jdbc.driver.OracleDriver
|
||||||
|
spring.datasource-kwms.jdbcUrl=jdbc:oracle:thin:@118.219.150.34:51521:kwms
|
||||||
|
spring.datasource-kwms.username=kwms
|
||||||
|
spring.datasource-kwms.password=dbnt0928
|
||||||
|
|
||||||
|
#jpa
|
||||||
|
spring.jpa.show-sql=false
|
||||||
|
spring.jpa.generate-ddl=false
|
||||||
|
spring.jpa.hibernate.naming.physical-strategy = org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
|
||||||
|
|
||||||
|
# MyBatis
|
||||||
|
mybatis.mapper-locations: mybatisMapper/*.xml
|
||||||
|
mybatis.configuration.map-underscore-to-camel-case=true
|
||||||
|
mybatis.type-aliases-package=com.dbnt.faisp.main.**.model
|
||||||
|
logging.level.com.atoz_develop.mybatissample.repository=TRACE
|
||||||
|
|
@ -1,5 +1,12 @@
|
||||||
|
#tomcat
|
||||||
tomcat.ajp.protocol=AJP/1.3
|
tomcat.ajp.protocol=AJP/1.3
|
||||||
#server.port=80
|
tomcat.cluster.enabled=true
|
||||||
|
#tomcat.cluster.static-member-host=10.187
|
||||||
|
#tomcat.cluster.static-member-port=50540
|
||||||
|
#tomcat.cluster.static-member-unique-id={0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2}
|
||||||
|
#tomcat.cluster.receiver-address=118.219.150.34
|
||||||
|
#tomcat.cluster.receiver-port=4042
|
||||||
|
#tomcat.cluster.receiver-max-threads=4
|
||||||
|
|
||||||
#file upload
|
#file upload
|
||||||
spring.servlet.multipart.location=/backup/faisp/uploadFiles
|
spring.servlet.multipart.location=/backup/faisp/uploadFiles
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
#tomcat
|
||||||
|
tomcat.ajp.protocol=AJP/1.3
|
||||||
|
tomcat.cluster.enabled=true
|
||||||
|
#tomcat.cluster.static-member-host=118.219.150.34
|
||||||
|
#tomcat.cluster.static-member-port=50540
|
||||||
|
#tomcat.cluster.static-member-unique-id={0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1}
|
||||||
|
#tomcat.cluster.receiver-address=118.219.150.34
|
||||||
|
#tomcat.cluster.receiver-port=4042
|
||||||
|
#tomcat.cluster.receiver-max-threads=4
|
||||||
|
|
||||||
|
#file upload
|
||||||
|
spring.servlet.multipart.location=/backup/faisp/uploadFiles
|
||||||
|
spring.servlet.multipart.max-file-size=200MB
|
||||||
|
spring.servlet.multipart.max-request-size=500MB
|
||||||
|
|
||||||
|
site.domain=10.187.58.12
|
||||||
|
|
||||||
|
#file
|
||||||
|
file.dir.publicBoard=/publicBoard
|
||||||
|
file.dir.faRpt=/faRpt
|
||||||
|
file.dir.vulnerable=/vulnerable
|
||||||
|
file.dir.part=/part
|
||||||
|
file.dir.equip=/equip
|
||||||
|
file.dir.sailor=/sailor
|
||||||
|
file.dir.affair=/affair
|
||||||
|
file.dir.affair.plan=/affairPlan
|
||||||
|
file.dir.affair.result=/affairResult
|
||||||
|
file.dir.editor=/editor
|
||||||
|
file.dir.sri=/sri
|
||||||
|
file.dir.ciw=/ciw
|
||||||
|
file.dir.cia.safty=/cia/safty
|
||||||
|
file.dir.cia.company=/cia/company
|
||||||
|
file.dir.cia.foreigner=/cia/foreigner
|
||||||
|
file.dir.cia.edu=/cia/edu
|
||||||
|
file.dir.activityCase=/activityCase
|
||||||
|
file.dir.majorStatus=/majorStatus
|
||||||
|
file.dir.monitoring=/monitoring
|
||||||
|
file.dir.intelligenceNetwork=/intelligenceNetwork
|
||||||
|
|
||||||
|
file.dir.affairTemp=/affairTemp
|
||||||
|
|
||||||
|
editor.img.view=/file/editorFileDisplay?fileNm=
|
||||||
|
|
||||||
|
#thymeleaf
|
||||||
|
spring.thymeleaf.prefix=classpath:templates/
|
||||||
|
spring.thymeleaf.check-template-location=true
|
||||||
|
spring.thymeleaf.suffix=.html
|
||||||
|
spring.thymeleaf.mode=HTML
|
||||||
|
|
||||||
|
#Datasource Configuration
|
||||||
|
spring.sql.init.encoding=utf-8
|
||||||
|
#maximum-pool-size: CPU core count
|
||||||
|
spring.datasource.hikari.maximum-pool-size=8
|
||||||
|
#postgresql
|
||||||
|
spring.datasource-main.driverClassName=org.postgresql.Driver
|
||||||
|
spring.datasource-main.jdbcUrl=jdbc:postgresql://10.187.142.13:5432/experdb
|
||||||
|
spring.datasource-main.username=faisp
|
||||||
|
spring.datasource-main.password=dbnt0928!
|
||||||
|
#tibero
|
||||||
|
spring.datasource-kwms.driverClassName=com.tmax.tibero.jdbc.TbDriver
|
||||||
|
spring.datasource-kwms.jdbcUrl=jdbc:tibero:thin:@10.188.171.206:9629:KCGHRDB
|
||||||
|
spring.datasource-kwms.username=KCGEXT
|
||||||
|
spring.datasource-kwms.password=kcgextuser
|
||||||
|
|
||||||
|
#jpa
|
||||||
|
spring.jpa.show-sql=false
|
||||||
|
spring.jpa.generate-ddl=false
|
||||||
|
spring.jpa.hibernate.naming.physical-strategy = org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
|
||||||
|
|
||||||
|
# MyBatis
|
||||||
|
mybatis.mapper-locations: mybatisMapper/*.xml
|
||||||
|
mybatis.configuration.map-underscore-to-camel-case=true
|
||||||
|
mybatis.type-aliases-package=com.dbnt.faisp.main.**.model
|
||||||
|
logging.level.com.atoz_develop.mybatissample.repository=TRACE
|
||||||
|
|
@ -7,10 +7,10 @@
|
||||||
</th:block>
|
</th:block>
|
||||||
<div layout:fragment="content">
|
<div layout:fragment="content">
|
||||||
<main>
|
<main>
|
||||||
<div class="row justify-content-between mx-0">
|
<div class="row justify-content-between mx-0 d-none">
|
||||||
<div class="mb-2">
|
<div class="mb-2">
|
||||||
<div class="d-inline align-middle"><i class="bi bi-square-fill"></i></div>
|
<div class="d-inline align-middle"><i class="bi bi-square-fill"></i></div>
|
||||||
<h5 class="d-inline align-middle"> 대시보드</h5>
|
<h5 class="d-inline align-middle" th:text="${#session.getId()}"></h5>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto mt-2">
|
<div class="col-auto mt-2">
|
||||||
<!--<a class="link-dark align-bottom" href="/myInfo/myInfoPage?activeTab=dashboard">대시보드 편집</a>-->
|
<!--<a class="link-dark align-bottom" href="/myInfo/myInfoPage?activeTab=dashboard">대시보드 편집</a>-->
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue