Prechádzať zdrojové kódy

添加 admin 模块, 本模块引入 tnb 项目依赖的所有第三方服务的原生客户端, 对第三方服务进行监控

reghao 1 mesiac pred
rodič
commit
4e9d41eb25

+ 208 - 0
admin/pom.xml

@@ -0,0 +1,208 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>tnb</artifactId>
+        <groupId>cn.reghao.tnb</groupId>
+        <version>1.0.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>admin</artifactId>
+
+    <properties>
+        <maven.compiler.source>17</maven.compiler.source>
+        <maven.compiler.target>17</maven.compiler.target>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>cn.reghao.tnb</groupId>
+            <artifactId>common</artifactId>
+            <version>1.0.0-SNAPSHOT</version>
+        </dependency>
+
+        <dependency>
+            <groupId>cn.reghao.tnb.search</groupId>
+            <artifactId>search-api</artifactId>
+            <version>1.0.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>cn.reghao.tnb.content</groupId>
+            <artifactId>content-api</artifactId>
+            <version>1.0.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>cn.reghao.tnb.user</groupId>
+            <artifactId>user-api</artifactId>
+            <version>1.0.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>cn.reghao.tnb.file</groupId>
+            <artifactId>file-api</artifactId>
+            <version>1.0.0-SNAPSHOT</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>com.mysql</groupId>
+            <artifactId>mysql-connector-j</artifactId>
+            <version>8.0.31</version>
+        </dependency>
+        <dependency>
+            <groupId>com.zaxxer</groupId>
+            <artifactId>HikariCP</artifactId>
+            <version>3.3.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>io.lettuce</groupId>
+            <artifactId>lettuce-core</artifactId>
+            <version>6.1.10.RELEASE</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.rabbitmq</groupId>
+            <artifactId>amqp-client</artifactId>
+            <version>5.19.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.mongodb</groupId>
+            <artifactId>mongodb-driver-sync</artifactId>
+            <version>4.11.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.kafka</groupId>
+            <artifactId>kafka-clients</artifactId>
+            <version>3.9.1</version> <!-- Use the latest compatible version -->
+        </dependency>
+
+        <!-- elasticsearch -->
+        <dependency>
+            <groupId>co.elastic.clients</groupId>
+            <artifactId>elasticsearch-java</artifactId>
+            <version>7.17.18</version>
+        </dependency>
+        <dependency>
+            <groupId>org.elasticsearch.client</groupId>
+            <artifactId>elasticsearch-rest-client</artifactId>
+            <version>7.17.18</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+            <version>2.17.0</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>com.fasterxml.jackson.core</groupId>
+                    <artifactId>jackson-core</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-core</artifactId>
+            <version>2.17.0</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-annotations</artifactId>
+            <version>2.17.0</version>
+        </dependency>
+        <dependency>
+            <groupId>jakarta.json</groupId>
+            <artifactId>jakarta.json-api</artifactId>
+            <version>2.0.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.alibaba.nacos</groupId>
+            <artifactId>nacos-client</artifactId>
+            <version>2.4.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springdoc</groupId>
+            <artifactId>springdoc-openapi-ui</artifactId>
+            <version>1.7.0</version>
+        </dependency>
+    </dependencies>
+
+    <profiles>
+        <profile>
+            <id>dev</id>
+            <properties>
+                <profile.active>dev</profile.active>
+            </properties>
+            <activation>
+                <activeByDefault>true</activeByDefault>
+            </activation>
+        </profile>
+        <profile>
+            <id>test</id>
+            <properties>
+                <profile.active>test</profile.active>
+            </properties>
+        </profile>
+        <profile>
+            <id>cluster</id>
+            <properties>
+                <profile.active>cluster</profile.active>
+            </properties>
+        </profile>
+    </profiles>
+
+    <build>
+        <finalName>tnb-admin</finalName>
+        <resources>
+            <resource>
+                <directory>src/main/resources</directory>
+                <filtering>true</filtering>
+                <includes>
+                    <include>application.yml</include>
+                    <include>application-${profile.active}.yml</include>
+                    <include>mapper/**</include>
+                    <include>*.xml</include>
+                </includes>
+            </resource>
+        </resources>
+
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.11.0</version>
+                <configuration>
+                    <compilerArgs>
+                        <arg>-parameters</arg>
+                    </compilerArgs>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>${springboot.version}</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>

+ 18 - 0
admin/src/main/java/cn/reghao/tnb/admin/AdminApplication.java

@@ -0,0 +1,18 @@
+package cn.reghao.tnb.admin;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchClientAutoConfiguration;
+import org.springframework.context.annotation.ComponentScan;
+
+/**
+ * @author reghao
+ * @date 2025-04-28 09:50:58
+ */
+@SpringBootApplication(exclude = ElasticsearchClientAutoConfiguration.class)
+@ComponentScan({"cn.reghao.tnb.admin", "cn.reghao.tnb.common"})
+public class AdminApplication {
+    public static void main(String[] args) {
+        SpringApplication.run(AdminApplication.class, args);
+    }
+}

+ 25 - 0
admin/src/main/java/cn/reghao/tnb/admin/config/SpringLifecycle.java

@@ -0,0 +1,25 @@
+package cn.reghao.tnb.admin.config;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.boot.ApplicationArguments;
+import org.springframework.boot.ApplicationRunner;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author reghao
+ * @date 2022-03-28 11:54:49
+ */
+@Slf4j
+@Component
+public class SpringLifecycle implements ApplicationRunner, DisposableBean {
+    @Override
+    public void run(ApplicationArguments args) {
+        log.info("AdminService 启动...");
+    }
+
+    @Override
+    public void destroy() {
+        log.info("AdminService 停止...");
+    }
+}

+ 63 - 0
admin/src/main/java/cn/reghao/tnb/admin/config/TokenFilter.java

@@ -0,0 +1,63 @@
+package cn.reghao.tnb.admin.config;
+
+import cn.reghao.tnb.common.auth.LoginUser;
+import cn.reghao.tnb.common.auth.UserContext;
+import cn.reghao.tnb.common.util.ConstantId;
+import cn.reghao.tnb.common.web.ServletUtil;
+import jakarta.servlet.*;
+import org.slf4j.MDC;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * HTTP 请求过滤器
+ *
+ * @author reghao
+ * @date 2025-07-18 09:18:16
+ */
+@Component
+public class TokenFilter implements Filter {
+    @Override
+    public void init(FilterConfig filterConfig) throws ServletException {
+    }
+
+    @Override
+    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
+            throws IOException, ServletException {
+        String requestId = ServletUtil.getHeader("x-request-id");
+        MDC.put("request_id", requestId);
+
+        long userId = ConstantId.ANONYMOUS_USER_ID;
+        String userIdStr = ServletUtil.getHeader("x-user-id");
+        if (userIdStr != null) {
+            userId = Long.parseLong(userIdStr);
+        }
+
+        String loginId = ConstantId.ANONYMOUS_USER_ID + "";
+        String loginIdStr = ServletUtil.getHeader("x-login-id");
+        if (loginIdStr != null) {
+            loginId = loginIdStr;
+        }
+
+        Set<String> roles = new HashSet<>();
+        String rolesStr = ServletUtil.getHeader("x-user-roles");
+        if (rolesStr != null) {
+            roles.addAll(Arrays.asList(rolesStr.split(",")));
+        }
+
+        LoginUser loginUser = new LoginUser(userId, loginId, roles);
+        try (UserContext context = new UserContext(loginUser)) {
+            chain.doFilter(request, response);
+        } finally {
+            MDC.clear();
+        }
+    }
+
+    @Override
+    public void destroy() {
+    }
+}

+ 22 - 0
admin/src/main/java/cn/reghao/tnb/admin/config/WebConfig.java

@@ -0,0 +1,22 @@
+package cn.reghao.tnb.admin.config;
+
+import jakarta.servlet.Filter;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+/**
+ * @author reghao
+ * @date 2025-07-18 09:18:16
+ */
+@Configuration
+public class WebConfig implements WebMvcConfigurer {
+    @Bean
+    public FilterRegistrationBean<Filter> filterRegistrationBean(TokenFilter tokenFilter) {
+        FilterRegistrationBean<Filter> registrationBean = new FilterRegistrationBean<>();
+        registrationBean.setFilter(tokenFilter);
+        registrationBean.addUrlPatterns("*");
+        return registrationBean;
+    }
+}

+ 33 - 0
admin/src/main/java/cn/reghao/tnb/admin/controller/AdminController.java

@@ -0,0 +1,33 @@
+package cn.reghao.tnb.admin.controller;
+
+import cn.reghao.tnb.admin.service.AdminService;
+import cn.reghao.tnb.common.db.SelectOption;
+import cn.reghao.tnb.common.web.WebResult;
+import io.swagger.v3.oas.annotations.Operation;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+/**
+ * @author reghao
+ * @date 2026-01-21 14:02:38
+ */
+@RestController
+@RequestMapping("/api/admin1")
+public class AdminController {
+    private final AdminService adminService;
+
+    public AdminController(AdminService adminService) {
+        this.adminService = adminService;
+    }
+
+    @Operation(summary = "", description = "N")
+    @GetMapping(value = "/stat", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String stat() {
+        adminService.stat();
+        return WebResult.success("admin stat");
+    }
+}

+ 13 - 0
admin/src/main/java/cn/reghao/tnb/admin/service/AdminService.java

@@ -0,0 +1,13 @@
+package cn.reghao.tnb.admin.service;
+
+import org.springframework.stereotype.Service;
+
+/**
+ * @author reghao
+ * @date 2026-01-21 14:12:16
+ */
+@Service
+public class AdminService {
+    public void stat() {
+    }
+}

+ 23 - 0
admin/src/main/resources/application-cluster.yml

@@ -0,0 +1,23 @@
+dubbo:
+  registry:
+    group: dubbo
+    address: zookeeper://192.168.0.211:2181?backup=192.168.0.212:2181,192.168.0.213:2181
+spring:
+  cloud:
+    discovery:
+      enabled: true
+  data:
+    redis:
+      database: 0
+      host: 192.168.0.211
+      port: 6379
+      password: Test@123456
+  rabbitmq:
+    addresses: 192.168.0.211:5672,192.168.0.212:5672,192.168.0.213:5672
+    virtual-host: /
+    username: test
+    password: Test@123456
+  datasource:
+    url: jdbc:mysql://192.168.0.211:3306/tnb_account_tdb?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2b8
+    username: test
+    password: Test@123456

+ 46 - 0
admin/src/main/resources/application-dev.yml

@@ -0,0 +1,46 @@
+dubbo:
+  registry:
+    group: dubbo
+    address: zookeeper://127.0.0.1:2181
+spring:
+  cloud:
+    discovery:
+      enabled: true
+  data:
+    mongodb:
+      host: 127.0.0.1
+      database: "tnb_content_rdb"
+      authentication-database: admin
+      username: dev
+      password: Dev@123456
+    redis:
+      database: 0
+      host: 127.0.0.1
+      port: 6379
+      password: Dev@123456
+  rabbitmq:
+    host: 127.0.0.1
+    port: 5672
+    virtual-host: /
+    username: dev
+    password: Dev@123456
+  datasource:
+    url: jdbc:mysql://127.0.0.1/tnb_account_rdb?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2b8
+    username: dev
+    password: Dev@123456
+eureka:
+  client:
+    service-url:
+      defaultZone: http://127.0.0.1:6060/eureka/
+app:
+  es-host: 192.168.0.81
+  es-port: 9200
+  es-username: elastic
+  es-password: VLTtN03SSJ4lsyyg56kf
+  kafka-uri: 192.168.0.81:9092
+  kafka-topic: NginxLog
+  base-dir: /opt/data/search_data
+  native-lucene-dirname: native_lucene
+  hibernate-lucene-dirname: hibernate_lucene
+  geoip-filename: qqwry.dat
+  geojson-filename: china1.json

+ 28 - 0
admin/src/main/resources/application-test.yml

@@ -0,0 +1,28 @@
+dubbo:
+  registry:
+    group: dubbo
+    address: zookeeper://192.168.0.209:2181
+spring:
+  cloud:
+    discovery:
+      enabled: true
+  data:
+    redis:
+      database: 0
+      host: 192.168.0.209
+      port: 6379
+      password: Test@123456
+  rabbitmq:
+    host: 192.168.0.209
+    port: 5672
+    virtual-host: /
+    username: test
+    password: Test@123456
+  datasource:
+    url: jdbc:mysql://192.168.0.209:3306/tnb_account_tdb?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2b8
+    username: test
+    password: Test@123456
+eureka:
+  client:
+    service-url:
+      defaultZone: http://192.168.0.210:6060/eureka/

+ 55 - 0
admin/src/main/resources/application.yml

@@ -0,0 +1,55 @@
+dubbo:
+  application:
+    register-consumer: false
+server:
+  port: 6010
+  tomcat:
+    max-http-form-post-size: 4MB
+  servlet:
+    session:
+      cookie:
+        secure: true
+        http-only: true
+        # org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getSessionTimeoutInMinutes 获取超时时间
+        # 两个请求间隔的最大时间, 超过此时间则会话过期
+      timeout: 10m
+spring:
+  application:
+    name: admin-service
+  profiles:
+    active: @profile.active@
+  mvc:
+    pathmatch:
+      matching-strategy: ant_path_matcher
+  servlet:
+    multipart:
+      max-request-size: 5MB
+      max-file-size: 5MB
+  session:
+    store-type: redis
+    redis:
+      namespace: tnb:auth:session
+  datasource:
+    driver-class-name: com.mysql.cj.jdbc.Driver
+    type: com.zaxxer.hikari.HikariDataSource
+    hikari:
+      minimum-idle: 5
+      maximum-pool-size: 10
+      auto-commit: true
+      idle-timeout: 30000
+      pool-name: EvaluationHikariCP
+      max-lifetime: 1800000
+      connection-timeout: 30000
+      connection-test-query: SELECT 1
+mybatis:
+  configuration:
+    map-underscore-to-camel-case: true
+#    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
+  mapper-locations: classpath*:mapper/**/**.xml
+  type-aliases-package: cn.reghao.tnb.admin.app.model.po
+eureka:
+  instance:
+    prefer-ip-address: true
+  client:
+    register-with-eureka: true
+    fetch-registry: true

+ 74 - 0
admin/src/main/resources/logback-spring.xml

@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<configuration>
+    <appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender">
+        <layout class="ch.qos.logback.classic.PatternLayout">
+            <pattern>
+                %d{HH:mm:ss.SSS} [%thread] %-5level %c %M %L - %msg%n
+            </pattern>
+        </layout>
+    </appender>
+
+    <!-- info 日志文件 -->
+    <appender name="fileInfoLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>ERROR</level>
+            <onMatch>DENY</onMatch>
+            <onMismatch>ACCEPT</onMismatch>
+        </filter>
+        <encoder>
+            <pattern>
+                %d{HH:mm:ss.SSS} %-5level %c %M %L - %msg%n
+            </pattern>
+            <charset>UTF-8</charset>
+        </encoder>
+        <!-- 滚动策略 -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <fileNamePattern>
+                logs/account-info.%d.log
+            </fileNamePattern>
+        </rollingPolicy>
+    </appender>
+
+    <!-- error 日志文件 -->
+    <appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+            <level>ERROR</level>
+        </filter>
+        <encoder>
+            <pattern>
+                %d{HH:mm:ss.SSS} %-5level %c %M %L - %msg%n
+            </pattern>
+            <charset>UTF-8</charset>
+        </encoder>
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <fileNamePattern>
+                logs/account-error.%d.log
+            </fileNamePattern>
+        </rollingPolicy>
+    </appender>
+
+    <springProfile name="dev">
+        <root level="info">
+            <appender-ref ref="consoleLog"></appender-ref>
+        </root>
+    </springProfile>
+    <springProfile name="test">
+        <root level="info">
+            <appender-ref ref="fileInfoLog"></appender-ref>
+            <appender-ref ref="fileErrorLog"></appender-ref>
+        </root>
+    </springProfile>
+    <springProfile name="prod">
+        <root level="info">
+            <appender-ref ref="fileInfoLog"></appender-ref>
+            <appender-ref ref="fileErrorLog"></appender-ref>
+        </root>
+    </springProfile>
+    <springProfile name="cluster">
+        <root level="info">
+            <appender-ref ref="fileInfoLog"></appender-ref>
+            <appender-ref ref="fileErrorLog"></appender-ref>
+        </root>
+    </springProfile>
+</configuration>

+ 1 - 0
pom.xml

@@ -23,6 +23,7 @@
         <module>oss</module>
         <module>sb</module>
         <module>oauth2</module>
+        <module>admin</module>
     </modules>
 
     <properties>