SprongBoot及其基础应用全套部署脚本和配置

news2024/11/15 18:44:57
POM.xml配置
</dependencies>    
	<!--skywalking日志监控依赖-->
	<dependency>
      <groupId>org.apache.skywalking</groupId>
      <artifactId>apm-toolkit-logback-1.x</artifactId>
      <version>8.5.0</version>
    </dependency>

    <dependency>
      <groupId>org.apache.skywalking</groupId>
      <artifactId>apm-toolkit-trace</artifactId>
      <version>8.5.0</version>
    </dependency>
</dependencies>

<build>
      <plugin>
        <groupId>com.spotify</groupId>
        <artifactId>docker-maven-plugin</artifactId>
        <version>1.0.0</version>
        <configuration>
          <!--生成的镜像名称,需要替换的地方-->
          <imageName>creatar</imageName>
          <!--覆盖旧镜像-->
          <forceTags>true</forceTags>
          <!--指定dockerfile文件所在目录,跟pom平级-->
          <dockerDirectory>${basedir}</dockerDirectory>
          <buildArgs>
            <!--指定需要复制的jar的名称,在dockerfile中会根据这个参数来将jar复制到容器中-->
            <JAR_FILE>${project.build.finalName}.jar</JAR_FILE>
          </buildArgs>
        </configuration>
      </plugin>
    </plugins>
</build>
logback日志配置
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <springProperty scope="context" name="log.path" source="logging.file.path"/>
    <!-- 日志输出格式 -->
    <property name="log.pattern"
              value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{50} - [methodName:%method,line:%line] - %msg%n"/>

    <!-- 控制台输出 -->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!-- 系统日志输出 -->
    <appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 循环政策:基于时间创建日志文件 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 日志文件名格式 -->
            <fileNamePattern>${log.path}/%d{yyyy-MM-dd}/%d{HH}/sys-info.log</fileNamePattern>
            <!-- 日志最大的历史 60天 -->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!-- 过滤的级别 只会打印info不会有info日志-->
            <level>INFO</level>
            <!-- 匹配时的操作:接收(记录) -->
            <onMatch>ACCEPT</onMatch>
            <!-- 不匹配时的操作:拒绝(不记录) -->
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 循环政策:基于时间创建日志文件 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 日志文件名格式 -->
            <fileNamePattern>${log.path}/%d{yyyy-MM-dd}/%d{HH}/sys-error.log</fileNamePattern>
            <!-- 日志最大的历史 60天 -->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!-- 过滤的级别 -->
            <level>ERROR</level>
            <!-- 匹配时的操作:接收(记录) -->
            <onMatch>ACCEPT</onMatch>
            <!-- 不匹配时的操作:拒绝(不记录) -->
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    
	<!--发送日志skywalking-->
    <appender name="SKYWALKING" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">
        <!-- 日志输出编码 -->
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>

    <!-- 系统模块日志级别控制  -->
    <logger name="com.example" level="info"/>
    <!-- Spring日志级别控制  -->
    <logger name="org.springframework" level="warn"/>

    <root level="info">
        <appender-ref ref="console"/>
        <appender-ref ref="SKYWALKING"/>
    </root>

    <!--系统操作日志-->
    <root level="info">
        <appender-ref ref="file_info"/>
        <appender-ref ref="file_error"/>
        <appender-ref ref="SKYWALKING"/>
    </root>

</configuration>
Dockerfile

Dockerfile文件跟pom文件平级

FROM eclipse-temurin:21
RUN mkdir /opt/app
ARG JAR_FILE
#看情况,自己要改复制到镜像中的名称也行,但是注意在ENTRYPOINT处启动的jar名称也要换
ADD target/${JAR_FILE} /opt/app/creatar.jar
#跟项目src文件平级的文件夹,后续会有截图
ADD base-app/skywalking/apache-skywalking-java-agent-9.1.0.tgz /opt/app/
#配置日志监控平台,跟后续的docker-compose呼应
ENV SW_AGENT_NAME=creatar
ENV SW_AGENT_COLLECTOR_BACKEND_SERVICES=creatar-skywalking-oap:11800
ENTRYPOINT ["java","-javaagent:/opt/app/skywalking-agent/skywalking-agent.jar","-jar","-Xms512m","-Xmx512m","/opt/app/creatar.jar"]
docker-compose
version: "1.0.0"
#创建Docker网络,用于容器间通信,通过容器名称访问
networks:
#容器名称,默认就是使用bridge模式,如果替换了名称,那本文件中后续所有关于networks节点的配置都要换名称
  creatar-networks:
services:
#应用镜像,镜像名称,在pom的imageName节点配置的是什么这里就写什么
  creatar:
    image: creatar:latest
    #应用容器名称,可换可不换
    container_name: creatar
    #限制容器内存大小
    deploy:
      resources:
        limits:
          memory: 1024MB
    networks:
      - creatar-networks
      #配置日志监控环境变量,用于初次运行时
    environment:
      - "SW_AGENT_NAME=creatar"
      - "SW_AGENT_COLLECTOR_BACKEND_SERVICES=creatar-skywalking-oap:11800"
    ports:
      - "9436:9436"
    restart: always
    #启动应用之前先启动redis、mysql、es
    depends_on:
      - "creatar-redis"
      - "creatar-mysql"
      - "creatar-elasticsearch"
    volumes:
      - ./base-app/creatar/logs:/opt/app/logs

#Redis容器
  creatar-redis:
    image: redis:7.2.4
    container_name: creatar-redis
    cap_add:
      - ALL
    command: redis-server  /etc/redis/redis.conf
    networks:
      - creatar-networks
    ports:
      - 9437:6379
    restart: always
    volumes:
      - ./base-app/redis/data:/data:rw
      - ./base-app/redis/conf/redis.conf:/etc/redis/redis.conf:rw
      - ./base-app/redis/logs:/logs:rw

#mysql容器
  creatar-mysql:
    image: mysql:8.2.0
    container_name: creatar-mysql
    cap_add:
      - ALL
    command:
      - "--default-authentication-plugin=caching_sha2_password"
    environment:
    #配置mysql的root用户密码
      - "MYSQL_ROOT_PASSWORD=creatar_mysql@yyds"
      #创建数据库
      - "MYSQL_DATABASE=creatar"
      #创建用户,该用户对MYSQL_DATABASE创建的数据库拥有所有权限
      - "MYSQL_USER=creatar"
      #新用户的密码
      - "MYSQL_PASSWORD=creatar9436"
      - "TZ=Asia/Shanghai"
    networks:
      - creatar-networks
    ports:
      - 9438:3306
    restart: always
    volumes:
      - ./base-app/mysql/data/:/var/lib/mysql:rw
      - ./base-app/mysql/log:/var/log/mysql:rw

#ES容器
  creatar-elasticsearch:
    image: elasticsearch:7.17.16
    container_name: creatar-elasticSearch
    deploy:
      resources:
        limits:
          memory: 3072MB
    cap_add:
      - ALL
    environment:
      - discovery.type=single-node
      #设置Es访问密码,用户名默认就是:elastic
      - ELASTIC_PASSWORD=creatar9436
      - xpack.security.enabled=true
      - ES_JAVA_OPTS=-Xlog:disable -Xlog:gc=debug:stderr -Xms2048m -Xmx3072m
      - PATH=/usr/share/elasticsearch/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
      - ELASTIC_CONTAINER=true
    networks:
      - creatar-networks
    ports:
      - 9439:9200
      - 9440:9300
    restart: always
    ulimits:
      memlock:
        hard: -1
        soft: -1
      nofile:
        hard: 65536
        soft: 65536
    volumes:
      - ./base-app/elasticSearch/data/data:/usr/share/elasticsearch/data:rw
      - ./base-app/elasticSearch/data/backup:/usr/share/elasticsearch/backup:rw
      - ./base-app/elasticSearch/data/conf/jvm.options:/usr/share/elasticsearch/config/jvm.options:rw

#创建日志监控收集工具,oap
  creatar-skywalking-oap:
    image: apache/skywalking-oap-server:9.0.0
    container_name: creatar-skywalking-oap
    cap_add:
      - ALL
    environment:
    #使用Es存储日志
      - "SW_STORAGE=elasticsearch"
      #ES地址,由于是同一网络所以就使用容器名称即可
      - "SW_STORAGE_ES_CLUSTER_NODES=creatar-elasticsearch:9200"
      #ES地址
      - "SW_ES_USER=elastic"
      #ES密码,就是在ES容器配置项目中设置的密码
      - "SW_ES_PASSWORD=creatar9436"
      - "TZ=Asia/Shanghai"
    networks:
      - creatar-networks
    ports:
    #端口暴露,skywalking需要暴露11800和12800
      - 9441:11800
      - 9442:12800
    restart: always
    #依赖于ES,需要等ES启动之后在启动
    depends_on:
      - "creatar-elasticsearch"
#日志监控界面容器
  creatar-skywalking-ui:
    image: apache/skywalking-ui:9.0.0
    container_name: creatar-skywalking-ui
    cap_add:
      - ALL
    environment:
    #skywalking-oap服务地址,使用容器名访问
      - "SW_OAP_ADDRESS=http://creatar-skywalking-oap:12800"
      - "TZ=Asia/Shanghai"
    networks:
      - creatar-networks
    ports:
    #UI界面需要暴露8080端口
      - 9443:8080
    restart: always
    depends_on:
    #依赖于Skywalking-oap服务
      - "creatar-skywalking-oap"
初次部署运行脚本
echo "开始构建应用镜像----------------"
#删除旧镜像
docker rmi $(docker images | grep creatar | awk '{print $3}')
#打包并使用dockerfile构建应用镜像
mvn clean package
mvn docker:build

#后续会有该目录的讲解
chmod -R 777 ./base-app

echo "开始构建基础应用---------------"
docker-compose up -d
#赋予权限
chmod 777 deploy.sh
#执行脚本
sh deploy.sh
卸载脚本

会将应用的Docker镜像删除,以及本次部署所用到的,应用容器,基础设施容器全部删除

#停止creatar容器
docker stop $(docker ps -a | grep creatar | awk '{print $1}')
#停止mysql容器
docker stop $(docker ps -a | grep creatar-mysql | awk '{print $1}')
#停止Redis容器
docker stop $(docker ps -a | grep creatar-redis | awk '{print $1}')
#停止skywalking-ui容器
docker stop $(docker ps -a | grep creatar-skywalking-ui | awk '{print $1}')
#停止skywalking-oap容器
docker stop $(docker ps -a | grep creatar-skywalking-oap | awk '{print $1}')
#停止ES容器
docker stop $(docker ps -a | grep creatar-elasticSearch | awk '{print $1}')

#删除creatar容器
docker rm $(docker ps -a | grep creatar | awk '{print $1}')
#删除creatar镜像
docker rmi $(docker images | grep creatar | awk '{print $3}')
#删除mysql容器
docker rm $(docker ps -a | grep creatar-mysql | awk '{print $1}')
#删除redis容器
docker rm $(docker ps -a | grep creatar-redis | awk '{print $1}')
#删除skywalking-ui容器
docker rm $(docker ps -a | grep creatar-skywalking-ui | awk '{print $1}')
#删除skywalking-oap容器
docker rm $(docker ps -a | grep creatar-skywalking-oap | awk '{print $1}')
#删除es容器
docker rm $(docker ps -a | grep creatar-elasticSearch | awk '{print $1}')
#删除Docker网络
docker network rm creatar_creatar-networks

#删除creatar应用数据
rm -rf ./base-app/creatar/logs/*

#清空mysql数据
rm -rf ./base-app/mysql/data/*
rm -rf ./base-app/mysql/log/*

#删除Redis数据
rm -rf ./base-app/redis/data/*
rm -rf ./base-app/redis/conf/redis.conf
#赋予权限
chmod 777 undeploy.sh
#执行脚本
sh undeploy.sh
应用更新

当jar报需要更新时使用

#拉取最新代码
git pull origin main
#停止容器
docker stop $(docker ps -a | grep creatar | awk '{print $1}')
#删除容器
docker rm $(docker ps -a | grep creatar | awk '{print $1}')
#删除旧镜像
docker rmi $(docker images | grep creatar | awk '{print $3}')
#构建镜像
mvn clean package
mvn docker:build
docker run -dit --restart=always -p 9436:9436 -m 512m --name creatar --network=creatar_creatar-networks $(docker images | grep creatar | awk '{print $3}') /bin/bash
chmod 777 build.sh
sh build.sh
base-app目录详解

该目录是和项目中的src文件夹平级的,当本项目所用到的所有容器启动之后,他们的数据卷都是挂载在这个目录的,里面包含了一些容器启动时的配置文件,以及第三方的一些包(例如Skywalking的插件tar包)

image-20240707181045340

在项目中按照这个结构创建即可,其中的**.gitkeep**文件只是为了占位而已,避免文件夹是空的提交不到Git上.

jvm.options

该文件是es启动时需要的,如果没有会报错,这个文件是本人在不使用数据卷挂载时启动ES之后复制出来的官方配置

################################################################
##
## JVM configuration
##
################################################################
##
## WARNING: DO NOT EDIT THIS FILE. If you want to override the
## JVM options in this file, or set any additional options, you
## should create one or more files in the jvm.options.d
## directory containing your adjustments.
##
## See https://www.elastic.co/guide/en/elasticsearch/reference/7.17/jvm-options.html
## for more information.
##
################################################################



################################################################
## IMPORTANT: JVM heap size
################################################################
##
## The heap size is automatically configured by Elasticsearch
## based on the available memory in your system and the roles
## each node is configured to fulfill. If specifying heap is
## required, it should be done through a file in jvm.options.d,
## and the min and max should be set to the same value. For
## example, to set the heap to 4 GB, create a new file in the
## jvm.options.d directory containing these lines:
##
## -Xms4g
## -Xmx4g
##
## See https://www.elastic.co/guide/en/elasticsearch/reference/7.17/heap-size.html
## for more information
##
################################################################


################################################################
## Expert settings
################################################################
##
## All settings below here are considered expert settings. Do
## not adjust them unless you understand what you are doing. Do
## not edit them in this file; instead, create a new file in the
## jvm.options.d directory containing your adjustments.
##
################################################################

## GC configuration
8-13:-XX:+UseConcMarkSweepGC
8-13:-XX:CMSInitiatingOccupancyFraction=75
8-13:-XX:+UseCMSInitiatingOccupancyOnly

## G1GC Configuration
# NOTE: G1 GC is only supported on JDK version 10 or later
# to use G1GC, uncomment the next two lines and update the version on the
# following three lines to your version of the JDK
# 10-13:-XX:-UseConcMarkSweepGC
# 10-13:-XX:-UseCMSInitiatingOccupancyOnly
14-:-XX:+UseG1GC

## JVM temporary directory
-Djava.io.tmpdir=${ES_TMPDIR}

## heap dumps

# generate a heap dump when an allocation from the Java heap fails; heap dumps
# are created in the working directory of the JVM unless an alternative path is
# specified
-XX:+HeapDumpOnOutOfMemoryError

# exit right after heap dump on out of memory error. Recommended to also use
# on java 8 for supported versions (8u92+).
9-:-XX:+ExitOnOutOfMemoryError

# specify an alternative path for heap dumps; ensure the directory exists and
# has sufficient space
-XX:HeapDumpPath=data

# specify an alternative path for JVM fatal error logs
-XX:ErrorFile=logs/hs_err_pid%p.log

## JDK 8 GC logging
8:-XX:+PrintGCDetails
8:-XX:+PrintGCDateStamps
8:-XX:+PrintTenuringDistribution
8:-XX:+PrintGCApplicationStoppedTime
8:-Xloggc:logs/gc.log
8:-XX:+UseGCLogFileRotation
8:-XX:NumberOfGCLogFiles=32
8:-XX:GCLogFileSize=64m

# JDK 9+ GC logging
9-:-Xlog:gc*,gc+age=trace,safepoint:file=logs/gc.log:utctime,pid,tags:filecount=32,filesize=64m

redis.conf

Redis容器的配置文件,其中也是配置了一些我个人的东西,例如连接密码呀等等,可以自己复制一份官方的配置文件进行修改即可,篇幅过长这里不做粘贴了

项目整体结构

image-20240707182235775

配置文件中的连接信息
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    #mysql地址,注意,这里因为应用和mysql容器是在一个网络内的,所以可以直接使用mysql的容器名称访问,并且端口号使用的是容器内部的端口号并不是暴露出来的端口号
    url: jdbc:mysql://creatar-mysql:3306/creatar?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true&allowPublicKeyRetrieval=true
    username: creatar
    password: creatar9436

  data:
    redis:
    #同理也是使用的容器名称,我这里是由于使用了SpringBoot3.3.0版本是这么配置的,具体的各位可以参考自己的配置
      url: redis://creatar9436@creatar-redis:6379
      lettuce:
        pool:
          max-wait: 3000ms
#这里由于项目中使用了Easy-es依赖操作ES,所以我这里是这么配置的
easy-es:
  enable:
  address: creatar-elasticsearch:9200
  username: elastic
  password: creatar9436


logging:
#指定日志配置文件
  config: classpath:logback-spring.xml
  level:
    web: error
    sql: debug
    com:
      baomidou:
        mybatisplus: debug
  file:
    path: ./logs/
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1906483.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

小试牛刀-Python生成solana Wallet公私钥

目录 1.编写目的 2.使用依赖 3.实现方法 3.1 Pynacl实现 3.2 ed25519实现 1.编写目的 在使用Python开发solana应用过程中,需要生成solana Wallet公私钥,以实现后续应用操作.这里将Python生成方法进行整理,方便日后的查阅,也能帮助到实现相关功能的朋友。 2.使用依赖 主要…

在 Vue 项目中使用 FullCalendar

1、先安装依赖包&#xff0c;根据自己的需求安装&#xff0c;建议使用cnpm安装&#xff0c;不然会很慢有时候会出现安装不上的情况。 npm i fullcalendar/vue --save npm i fullcalendar/core --save // 在月视图或日视图中操作事件 npm i fullcalendar/daygrid --save // 在…

[数仓]三、离线数仓(Hive数仓系统)

第1章 数仓分层 1.1 为什么要分层 DIM&#xff1a;dimensionality 维度 1.2 数据集市与数据仓库概念 1.3 数仓命名规范 1.3.1 表命名 ODS层命名为ods_表名DIM层命名为dim_表名DWD层命名为dwd_表名DWS层命名为dws_表名 DWT层命名为dwt_表名ADS层命名为ads_表名临时表命名为…

Java-Redis-Clickhouse-Jenkins-MybatisPlus-Zookeeper-vscode-Docker

文章目录 Clickhouse基础实操windows docker desktop 下载clickhousespringboot项目配置clickhouse Redis谈下你对Redis的了解&#xff1f;Redis一般都有哪些使用的场景&#xff1f;Redis有哪些常见的功能&#xff1f;Redis支持的数据类型有哪些&#xff1f;Redis为什么这么快…

python安装PyTorch+cuda

1,最终结果 import torchprint(torch.cuda.is_available()) #显示True&#xff0c;则安装成功 print(torch.__version__)#打印当前PyTorch版本号。 print(torch.version.cuda)#打印当前CUDA版本号。 print(torch.backends.cudnn.version())# 打印当前cuDNN版本号。 print(torc…

PHP红包拓客微信小程序系统源码

&#x1f389;红包狂欢&#xff0c;客源滚滚来&#xff01;红包拓客微信小程序&#xff0c;营销新利器&#x1f680; &#x1f9e7;一、创意红包&#xff0c;吸引眼球 你还在为如何吸引顾客而烦恼吗&#xff1f;红包拓客微信小程序来帮你&#xff01;&#x1f381; 它以创意红…

网上怎么样可以挣钱,分享几种可以让你在家赚钱的兼职项目

当今社会&#xff0c;压力越来越大&#xff0c;工作、家庭、生活等等&#xff0c;方方面面都需要钱&#xff0c;仅靠一份工作赚钱&#xff0c;已经很难满足我们的需求。所以很多人都会尝试做一些副业&#xff0c;兼职来补贴家用。 现在呢&#xff0c;有很多人都想在网上赚钱&am…

基于Spring Boot的先进时尚室内管理系统

1 项目介绍 1.1 研究背景 随着21世纪信息技术革命的到来&#xff0c;互联网的普及与发展对人类社会的演变产生了深远影响&#xff0c;跨越了物质生活的丰盈边界&#xff0c;更深层次地滋养了人类的精神文化生活。在过去&#xff0c;囿于地理位置和技术条件的限制&#xff0c;…

Mybatis-Plus一文详解BaseMapper和Service 使用

Mybatis-Plus简介 MyBatis-Plus (opens new window)&#xff08;简称 MP&#xff09;是一个MyBatis (opens new window)的增强工具&#xff0c;在 MyBatis 的基础上只做增强不做改变&#xff0c;为简化开发、提高效率而生。 特性&#xff1a; 无侵入&#xff1a;只做增强不做…

OpenAI年初安全事件引发内部分裂

&#x1f989; AI新闻 &#x1f680; OpenAI年初安全事件引发内部分裂 摘要&#xff1a;《纽约时报》报道&#xff0c;OpenAI于2023年初发生安全事件&#xff0c;黑客入侵公司内部邮件系统&#xff0c;窃取敏感讨论信息&#xff0c;但未涉及客户数据和源代码。因未向执法部门…

黑马点评报错@user_script:17: user_script:17: attempt to compare nil with number

后面发现是需要预先写入缓存seckill:stock:11&#xff0c;其中11是优惠券id 我数据库里面是11 &#xff0c;这里redis里面也写了11之后就好使了

AI自动生成PPT怎么用?看完这篇文章你就知道啦

小暑&#xff0c;作为夏季的第五个节气&#xff0c;标志着炎炎夏日的正式到来。在这个时节&#xff0c;阳光明媚&#xff0c;万物生长&#xff0c;人们的心情也随着气温的升高而变得热烈。 然而&#xff0c;对于许多职场人士来说&#xff0c;小暑的到来也意味着需要准备各种汇报…

桑基气泡图 – 5个维度展示KEGG通路富集结果

2022年发表在《Nature communication》上的文章Kir2.1-mediated membrane potential promotes nutrient acquisition and inflammation through regulation of nutrient transporters fig1i使用微生信平台绘制了一张图&#xff0c;我们将其命名为“桑基气泡图”。从此&#xff…

Spring事务的进阶。@Transactional的rollbackFor和propagation属性。

1.3 事务进阶 前面我们通过spring事务管理注解Transactional已经控制了业务层方法的事务。接下来我们要来详细的介绍一下Transactional事务管理注解的使用细节。我们这里主要介绍Transactional注解当中的两个常见的属性&#xff1a; 异常回滚的属性&#xff1a;rollbackFor &…

拿客户电脑,用豆包IDE逆天改命完成需求紧急开发!被公司奖励500!

故事背景 原文链接&#xff1a;拿客户电脑&#xff0c;用豆包IDE逆天改命完成需求紧急开发&#xff01;被公司奖励500&#xff01; 前几天&#xff0c;业务拉了一个大客户&#xff0c;客户需要先看我们做的样本项目&#xff08;类似于官网首页&#xff09;&#xff0c;然后才…

一个php文件怎么实现联系表单自动发送邮件

学习PHP&#xff1a;如何编写一个自动发送邮件的联系表单处理器&#xff1f; 无论是反馈意见、业务咨询&#xff0c;还是技术支持&#xff0c;联系表单都能为用户提供便捷的交流途径。AokSend将探讨如何通过一个PHP文件实现联系表单的自动发送邮件功能。 php文件&#xff1a;…

移除元素合并两个有序数组-LeetCode

一、移除元素 . - 力扣&#xff08;LeetCode&#xff09; 题目描述&#xff1a; int removeElement(int* nums, int numsSize, int val) {int src0;int dst0;while(src<numsSize){if(nums[src]val){src;}else if (nums[src]!val){nums[dst]nums[src];src;dst;}}return dst…

Java线程的创建·启动和休眠

一.线程的创建和启动 Java中创建线程的两种方式 ◆继承java.lang.Thread类 ◆实现java.lang.Runnable接口 ◆使用线程的步骤 继承Thread类创建线程 ◆自定义线程类继承自Thread类 ◆重写run()方法&#xff0c;编写线程执行体 ◆创建线程对象&#xff0c;调用start()方法启动…

排序的总结

排序的性质 稳定性 相同的值相对顺序不变&#xff0c;对于结构体排序有意义 排序的比较 插入排序&#xff1a;时间复杂度&#xff1a;O(N^2),空间复杂度&#xff1a;O(1),稳定性&#xff1a;稳定 希尔排序&#xff1a;时间复杂度&#xff1a;O(N^1.3),空间复杂度&#xff1…

Web 基础与HTTP 协议

域名的概述 (1 )域名的结构 (2 )域名结构类型 根域&#xff1a;指的是根服务器&#xff0c;要用来管理互联网的主目录&#xff0c;全世界只有13台。1个为 主根服务器&#xff0c;放置在美国。其余12 个均为辅根服务器&#xff0c;其中9个放置在美国&#xff1b;欧 洲2个&…