首页
友链
关于
免责声明
Search
1
王者营地战绩数据王者荣耀查询网页源码
6,209 阅读
2
群晖Active Backup for Business套件备份Linux服务器教程
4,384 阅读
3
影视分享
4,313 阅读
4
(亲测)Jrebel激活破解方式2019-08-21
4,289 阅读
5
centos7 安装及卸载 jekenis
3,573 阅读
日常
文章
后端
前端
Linux
异常
Flutter
分享
群辉
登录
Search
标签搜索
docker
springboot
Spring Boot
java
linux
Shiro
Graphics2D
图片
游戏账号交易
Mybatis
Spring Cloud
centos
脚本
Web Station
群辉
王者营地
战绩查询
平台对接
Spring Cloud Alibaba
nacos
绿林寻猫
累计撰写
249
篇文章
累计收到
26
条评论
首页
栏目
日常
文章
后端
前端
Linux
异常
Flutter
分享
群辉
页面
友链
关于
免责声明
搜索到
5
篇与
springboot
的结果
2023-07-26
Spring Cloud Alibaba 系列之 Nacos 篇(配置中心)
一、前言上一篇 Spring Cloud Alibaba 系列之 Nacos 篇(服务注册与发现) 介绍了 Nacos 的服务注册与发现,本篇接续介绍其另一个功能--配置中心。二、简单介绍Nacos 提供用于存储配置和其他元数据功能,为分布式系统中的外部化配置提供服务器端和客户端支持,使用 Spring Cloud Alibaba Nacos Config 就可以在 Nacos Server 集中管理 Spring Cloud 应用的外部属性配置。2.1 实现目的不使用配置中心之前,我们在管理项目配置会遇到如下问题:{message type="info" content="配置文件相对分散。在一个微服务架构下,配置文件会随着微服务的增多变的越来越多,而且分散在各个微服务中,不好统一配置和管理。配置文件无法区分环境。微服务项目可能会有多个环境,例如:测试环境、预发布环境、生产环境。每一个环境所使用的配置理论上都是不同的,一旦需要修改,就需要我们去各个微服务下手动维护,这比较困难。配置文件无法实时更新。我们修改了配置文件之后,必须重新启动微服务才能使配置生效,这对一个正在运行的项目来说是非常不友好的。"/}这些问题通过使用 Nacos 的配置中心功能快捷、简便的解决。2.2 基础概念为了区分环境或项目间的配置,我们需要了解 Nacos 给出的如下3个概念:{message type="warning" content=" 命名空间(Namespace)命名空间可用于进行不同环境的配置隔离。一般一个环境划分到一个命名空间"/}{message type="warning" content=" 配置分组(Group)命配置分组用于将不同的服务可以归类到同一分组。一般将一个项目的配置分到一组"/}{message type="warning" content=" 配置集(Data ID)在系统中,一个配置文件通常就是一个配置集。一般微服务的配置就是一个配置集"/}三者关系如下图: 三、实战演练首要条件就是启动 Nacos 的服务环境。我们使用上一篇文章搭建好的 Nacos 服务,不清楚的读者可以先移步至上一篇浏览前置内容。3.1 基础配置搭建名为 nacos-config 的springboot项目 🔧 第一步,添加依赖:<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.demo</groupId> <artifactId>nacos</artifactId> <version>1.0.0</version> </parent> <packaging>jar</packaging> <artifactId>nacos-config</artifactId> <description> 配置中心 </description> <properties> <java.version>1.8</java.version> <!--编译项目不生成测试类也不进行测试--> <maven.test.skip>true</maven.test.skip> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> </dependencies> <dependencyManagement> <dependencies> <!-- spring cloud 依赖 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Hoxton.SR3</version> <type>pom</type> <scope>import</scope> </dependency> <!-- spring cloud alibaba 依赖--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>2.2.1.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> 🔧 第二步,创建 bootstrap.properties 或 bootstrap.yml 文件: 使用配置中心后,我们通常会把 application.properties 或 application.yaml 中的配置移植到 Nacos 服务上,但项目连接配置中心服务需要单独配置,因此需要用到 bootstrap.properties 或 bootstrap.yml 文件。其中,这 4 种文件的加载顺序由高到低依次是:{message type="info" content=" 📢 bootstrap.properties -> bootstrap.yml -> application.properties -> application.yml"/}我们的 bootstrap.yml 配置如下:server: port: 38001 spring: application: # 应用名 name: nacos-config cloud: nacos: config: server-addr: 127.0.0.1:8848 # namespace: public group: DEFAULT_GROUP file-extension: yaml # 配置格式(默认是 properties) # 连接注册中心的账号和密码 以下是默认账密 username: nacos password: nacos 🔧 第三步,移植配置数据: 即将 application.properties 或 application.yml 中的业务配置数据移植到配置中心服务上。本次演练,我们使用如下配置数据进行测试:www: name: www.maven.vip 登录 Nacos 管理后台,管理配置 -> 配置列表,,操作如下图:在新建配置界面中, Data ID 通常对应 spring.application.name 的值 + (.properties 或 .yaml)。数据配置格式,目前只支持 properties 和 yaml。 🔧 第四步,创建测试类: 用于封装上文在 Nacos 服务上配置的数据@Data @Component @ConfigurationProperties(prefix = "www") public class DataBaseConfig { private String name; }用于测试获取配置数据@RestController @RefreshScope public class ConfigController { @Autowired private DataBaseConfig dataBaseConfig; // @Value注解可以获取到配置中心的值,但是无法动态感知修改后的值,需要利用@RefreshScope注解 @Value("${www.name}") private String name; @RequestMapping("/getConfig") public String getConfig() { return dataBaseConfig.getName(); } @RequestMapping("/getName") public String getName() { return name; } }接下来进行接口请求测试,启动项目,请求 🎈 http://127.0.0.1:38001/getConfig 结果如下图:成功请求获取配置中心的数据。3.2 动态刷新所谓动态刷新就是在不重启项目的基础上,修改配置中心的数据,项目能立即获取最新数据,接下来我们操作一遍:将配置数据改成:www: name: www.baidu.com修改配置后,不重启项目,再次请求接口,成功获取修改后的配置数据。3.3 环境隔离项目开发一般分为,开发、测试、预发和生产这4个阶段,每个阶段都有对应的配置数据(数据库、redis、MQ 连接配置等),这些数据都各不相同,为了更好的区分和维护这些数据,环境隔离功能必不可少。那配置中心如何做环境隔离呢?需要用到上文提到的命名空间,操作如下:📍 第一步,登录 Nacos 管理后台,命名空间菜单,新建一个名为 TEST 的命名空间:该命名空间就作为测试环境的专属空间。📍 第二步,在新建的命名空间下,创建一个配置:www: name: test📍 第三步,修改项目中的 bootstrap.properties 或 bootstrap.yml 文件,新增:server: port: 38001 spring: application: # 应用名 name: nacos-config cloud: nacos: config: server-addr: 127.0.0.1:8848 #此处就是创建 TEST 命名空间生成的 id 值 namespace: c716de35-9cb2-4c82-b86b-c74854ef726b group: DEFAULT_GROUP file-extension: yaml # 配置格式(默认是 properties) # 连接注册中心的账号和密码 以下是默认账密 username: nacos password: nacos最后,重启项目,请求接口,结果如下图:成功请求 TEST 命名空间下的配置数据。3.4 数据持久化Nacos 默认情况下是采用 apache derby 内嵌数据库进行数据存储,在单机模式时可以使用 Nacos 嵌入式数据库实现数据存储,但是 derby 数据库不方便观察数据存储的基本情况,从 Nacos 0.7 版本开始增加了支持 mysql 数据源能力。接下来,我们实现持久化功能。📍 第一步,创建名为 nacos_config 的数据库,在 Nacos 的程序包下,有个 conf 目录,将里边的 nacos-mysql.sql 导入到新建的数据库中。📍 第二步,修改 conf/application.properties 的数据库连接配置:将注释打开:spring.datasource.platform=mysql db.num=1 # 注意修改数据库名、账号和密码 db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC db.user.0=root db.password.0=tiger📍 第三步,重启 Nacos 服务,再次访问 http://localhost:8848/nacos ,如下图:登录发现,之前配置的数据都消失,因为我们更换了存储源( MySQL )。现在数据库中的数据都是空的,在 Nacos 管理后台中,我们尝试新建一条配置:database.url=abc database.username=root database.password=riger保存后,查看数据库信息,如下图:配置数据成功持久化。3.5 集群部署为保证配置中心的高可用性,集群部署是必不可少的整合方案。我们在本地测试,将 Nacos 安装包拷贝成 3 份,在持久化模式的基础上,操作步骤如下:📍 第一步,将 Nacos 程序包下的 conf/cluster.conf.example 改名为 conf/cluster.conf ,修改内容:127.0.0.1:8801 127.0.0.1:8802 127.0.0.1:8803📍 第二步,修改 3 份 Nacos 安装包下的 conf/application.properties 文件,将 server.port 依次改成 8801,8802,8803 。保存后,启动 3 份 Nacos 即可:cd nacos/bin # windows 单机模式启动 startup.cmd # linux/mac ./startup.sh注意,启动命令无需加 -m standalone 参数引申问题: Nacos 做了集群,有 3 个访问地址,客户端如何配置请求呢?有 2 种请求方案:修改 spring.cloud.nacos.discovery.server-addr=127.0.0.1:8801,127.0.0.1:8802,127.0.0.1:8803使用 Nginx 反向代理 Nacos 集群。四、参考资料📣 Nacos 官网五、项目源码📣 源码
2023年07月26日
2,258 阅读
2 评论
0 点赞
2023-07-26
Spring Cloud Alibaba 系列之 Nacos 篇(服务注册与发现)
一、前言Nacos 是阿里巴巴于2018年7月推出来的一个开源项目,是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。Nacos 提供了一组简单易用的特性集,帮助开发者快速实现动态服务发现、服务配置、服务元数据及流量管理。{alert type="info"} ::(灯泡) 其关键特性:服务发现和服务健康监测动态配置服务动态 DNS 服务服务及其元数据管理{/alert}Nacos 的功能包含 Spring Cloud 组件中的 Spring Cloud Eureka 和 Spring Cloud Config ,本篇章先介绍 Nacos 的服务注册与发现功能。二、环境搭建Nacos 作为服务注册发现中心,其运行原理与 Spring Cloud Eureka 大致相同,都由注册中心,服务提供者,服务消费者 3 部分组成和运作。如下图:与 Spring Cloud Eureka 不同的是, Nacos 服务无需开发者引入 Jar 依赖搭建,只需下载 官网 提供的安装包,解压启动即可。强调一下,安装 Nacos服务需要满足一下条件:64 bit OS64 bit JDK 1.8+Maven 3.2.x+ Nacos官方提供 2 种安装方式:① GitHub 上下载源码,编译安装启动,② 直接下载编译好的安装包。笔者选择第二种,点击 :@(抠鼻) Nacos releases 选择 1.4.6 版本的 .zip 文件下载。本地解压,如下图:💻 执行如下命令:cd nacos/bin # windows 单机模式启动 startup.cmd -m standalone # linux/mac ./startup.sh -m standalone启动成功后,打开浏览器输入 ::(OK) http://localhost:8848/nacos 可以访问Nacos后台管理界面,默认账户 nacos/nacos,如下图:至此 Nacos 服务注册中心环境搭建成功。三、实战演练注册中心服务搭建完成,现在开始搭建服务提供者和服务消费者。我们搭建如下 3 个项目:项目端口说明springCloudAlibabaDemo-pom 类型的父项目nacos-discovery-provider18001子项目,服务提供者nacos-discovery-consumer28001子项目,服务消费者3.1 搭建父工程创建名为 springCloudAlibabaDemo 的 Maven 项目,修改 pom.xml 文件:<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.demo</groupId> <artifactId>nacos</artifactId> <version>1.0.0</version> <name>maven</name> <url>https://www.maven.vip</url> <description>demo</description> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.version> </properties> <modules> <module>nacos-discovery-provider</module> <module>nacos-discovery-consumer</module> </modules> <packaging>pom</packaging> <dependencyManagement> <dependencies> <!-- spring boot 依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.2.5.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> <!-- spring cloud 依赖 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Hoxton.SR3</version> <type>pom</type> <scope>import</scope> </dependency> <!-- spring cloud alibaba 依赖--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>2.2.1.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>${java.version}</source> <target>${java.version}</target> <encoding>${project.build.sourceEncoding}</encoding> </configuration> </plugin> </plugins> </build> <repositories> <repository> <id>public</id> <name>aliyun nexus</name> <url>http://maven.aliyun.com/nexus/content/groups/public/</url> <releases> <enabled>true</enabled> </releases> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>public</id> <name>aliyun nexus</name> <url>http://maven.aliyun.com/nexus/content/groups/public/</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> </pluginRepository> </pluginRepositories> </project> 3.2 搭建服务提供者创建名为 nacos-discovery-provider 的 Maven 子项目。 📜 修改 pom.xml 文件:<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <groupId>com.demo</groupId> <artifactId>nacos</artifactId> <version>1.0.0</version> </parent> <modelVersion>4.0.0</modelVersion> <packaging>jar</packaging> <artifactId>nacos-discovery-provider</artifactId> <description> 服务提供者 </description> <properties> <java.version>1.8</java.version> <!--编译项目不生成测试类也不进行测试--> <maven.test.skip>true</maven.test.skip> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- nacos 服务注册与发现依赖 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> 📜 创建 application.ymlserver: port: 18001 spring: application: # 应用名 name: nacos-provider cloud: nacos: discovery: # 注册中心地址 server-addr: 127.0.0.1:8848 # 连接注册中心的账号和密码 以下是默认账密 username: nacos password: nacos 📜 编写提供接口:@RestController @RequestMapping("api") public class IndexController { @RequestMapping("hello/{content}") public String hello(@PathVariable("content") String content){ return "hello,"+content; } }📜 修改启动类:@EnableDiscoveryClient @SpringBootApplication public class NacosDiscoveryProviderApplication { public static void main(String[] args) { SpringApplication.run(NacosDiscoveryProviderApplication.class, args); } }在启动类上添加@EnableDiscoveryClient注解。运行服务提供者,再次访问 🎈 http://localhost:8848/nacos ,效果图如下:至此服务注册成功。3.3 搭建服务消费者创建名为 nacos-discovery-consumer 的 Maven 项目。📜 修改 pom.xml 文件:<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <groupId>com.demo</groupId> <artifactId>nacos</artifactId> <version>1.0.0</version> </parent> <modelVersion>4.0.0</modelVersion> <packaging>jar</packaging> <artifactId>nacos-discovery-consumer</artifactId> <description> 服务消费者 </description> <properties> <java.version>1.8</java.version> <!--编译项目不生成测试类也不进行测试--> <maven.test.skip>true</maven.test.skip> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- ribbon 依赖,实现客户端负载均衡 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> <version>2.2.2.RELEASE</version> </dependency> <!-- nacos 服务注册与发现依赖 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> ::(灯泡) 注意:SpringCloudAlibaba 依然采用 Ribbon 作为负载均衡客户端访问远程服务。 📜 创建 application.ymlserver: port: 28001 spring: application: # 应用名 name: nacos-consumer cloud: nacos: discovery: # 注册中心地址 server-addr: 127.0.0.1:8848 # 连接注册中心的账号和密码 以下是默认账密 username: nacos password: nacos 📜 创建消费接口:@RestController @RequestMapping("open") public class IndexController { @Autowired private RestTemplate restTemplate; @RequestMapping(value = "{content}") public String hello(@PathVariable String content) { // url = http://服务提供者的应用名称/接口名称/参数 return restTemplate.getForObject("http://nacos-provider/api/hello/" + content, String.class); } }📜 修改启动类@EnableDiscoveryClient @SpringBootApplication public class NacosDiscoveryConsumerApplication { public static void main(String[] args) { SpringApplication.run(NacosDiscoveryConsumerApplication.class, args); } @LoadBalanced @Bean public RestTemplate restTemplate() { return new RestTemplate(); } }在启动类上添加@EnableDiscoveryClient注解,同时创建RestTemplate实例并配置负载均衡。启动后,我们访问消费端接口 🎈 http://127.0.0.1:28001/open/Uncle ,结果如下图:消费者通过 Nacos 注册中心获取服务提供者的信息,成功调用其接口。更多详细资料请点击下方的链接进行查看。四、参考资料📣 Nacos 官网 📣 Nacos discovery wiki五、项目源码📣 源码
2023年07月26日
225 阅读
0 评论
0 点赞
2022-01-19
jenkins自动部署springboot项目 手把手图示教程
前提系统确保装了jdk、maven、git全局配置系统-全局工具配置 构建项目构建一个Maven项目 如果没有这个maven,去系统管理-插件管理,安装一个maven插件 配置git项目选择自己要构建的分支 添加凭证 centos安装git并配置密钥公钥 《centos安装git并配置密钥公钥》构建触发器如果没有webhook可以去插件中安装 配置webhook令牌 构建环境 #!/bin/bash #第一次编译可查看当前编译目录,后面可将输出的路径配置到jar_path,改为正确的路径 pwd #export BUILD_ID=dontKillMe这一句很重要,这样指定了,项目启动之后才不会被Jenkins杀掉。 export BUILD_ID=dontKillMe #指定最后编译好的jar存放的位置 www_path=/www/java/manage/ #Jenkins中编译好的jar位置 jar_path=/var/lib/jenkins/workspace/demo/admin/target/ #Jenkins中编译好的jar名称 jar_name=admin.jar #端口号 port=81 #获取运行编译好的进程ID,便于我们在重新部署项目的时候先杀掉以前的进程 pid=$(netstat -nlp | grep :$port | awk '{print $7}' | awk -F"/" '{ print $1 }') echo "admin used pid=${pid}" if [ -n "${pid}" ]; then kill -9 ${pid} fi #进入指定的编译好的jar的位置 cd ${jar_path} #将编译好的jar复制到最后指定的位置,直接覆盖 \cp -rf ${jar_path}/${jar_name} ${www_path} #进入最后指定存放jar的位置 cd ${www_path} #杀掉以前可能启动的项目进程 #kill -9 ${pid} #启动jar,指定SpringBoot的profiles为test,后台启动 nohup java -jar ${jar_name} --server.port=${port} &最后保存就好了
2022年01月19日
146 阅读
0 评论
0 点赞
2022-01-17
windows通过脚本自动打包部署springboot项目,并上传服务器启动
前提准备安装PuTTY 安装WinSCP创建脚本首先在项目目录下新建bin文件夹存放.bat文件,然后新建put.bat编写脚本put.bat@echo off echo. echo [信息] 打包Web工程,生成war/jar包文件。 echo. %~d0 cd %~dp0 cd ../ call mvn clean package -Dmaven.test.skip=true echo [信息]打包完成 echo [信息]准备上传... :: 先备份当前目录路径 set oldPath=%cd% :: 设置winscp安装目录(这里修改为个人实际的安装路径) set winscpInstallDir=D:\software\winscp :: 设置PuTTY安装目录(这里修改为个人实际的安装路径) set puTTYInstallDir=D:\software\PuTTY :: 远程主机linux IP :: 如果不需要命令行输入可以直接写死, 如: set ipaddr=110.11.11.11 :: set /p ipaddr=请输入目标主机IP: :: 登录用户名 :: 如果不需要命令行输入可以直接写死, 如: set username=root :: set /p username=username: :: 登录密码(注意啦!!!!) :: 如果密码中存在 & @ 等特殊字符时,请输入 ^ 用与转义 :: 至于这里为什么需要连续3个^,是因为密码在set password中被转义一次,在打开远程连接的时候会再被转义一次 :: 如: admin^^^@123^^^&456 ==> admin^^@123^^&456 ==> admin^@123^&456 ==> admin@123&456 :: 声明变量 ==》 set赋值转义一次 ==》往winscp.txt中写时候再转义一次 ==》 实际执行时候 :: 如果不需要命令行输入可以直接写死(也需要转义), 如: :: set password=123456 set /p password=password: :: 设置需要上传的文件,可找到打包好项目(jar/war) set localFilePath=D:\project\demo.jar :: 保存的linux远程目录 set remotePath=/www/project/ :: 打印提示信息 Echo 准备推送文件到远程服务器... :: 生成winscp执行的脚本 Echo option batch on > winscp.txt Echo option confirm off > winscp.txt :: 打开远程链接 :: 如果用户名或密码带有特殊字符,推荐直接在这里写死(也需要转义) :: 密码与ip之间的@符号,也需要转义 写为^@ Echo open %username%:%password%^@%ipaddr% > winscp.txt :: 进入到目标文件夹 Echo cd %remotePath% >> winscp.txt Echo option transfer binary >> winscp.txt :: 上传到远程 Echo put %localFilePath% >> winscp.txt Echo close >> winscp.txt Echo exit >> winscp.txt :: 到winscp.com 所在盘符 cd %winscpInstallDir% :: 使用winscp将文件上传到远程服务器,script为生成的步骤文件 winscp.com /console /script=%oldPath%\winscp.txt :: 删除本次上传生成的winscp.txt cd %oldPath% del winscp.txt Echo 推送完成... :: 到PuTTY 所在盘符 cd %puTTYInstallDir% :: 使用PuTTY执行linux脚本命令,test.sh为linux上执行的命令 Echo 开始启动... putty.exe -ssh -pw %password% -m d:/test.sh %username%^@%ipaddr% Echo 结束... pausetest.sh其中start.sh为linux目录中的执行文件,可参考 《linux脚本执行kill进程并重启》 #!/bin/sh cd /www/project/ #mkdir /tmp/test061502 sh start.sh #mkdir test06170
2022年01月17日
2,225 阅读
0 评论
0 点赞
2021-12-08
SpringBoot +Mybatis druid多数据源
配置依赖导入 <!-- springboot,druid 整合包 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency> <!--aop--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <!-- springboot,mybatis 整合包 --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.2</version> </dependency> <!--mysql--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.46</version> </dependency>application.yml# 开发环境配置 server: # 服务器的HTTP端口,默认为80 port: 80 servlet: # 应用的访问路径 context-path: / tomcat: # tomcat的URI编码 uri-encoding: UTF-8 # tomcat最大线程数,默认为200 max-threads: 800 # Tomcat启动初始化的线程数,默认值25 min-spare-threads: 30 # Spring配置 spring: # 模板引擎 thymeleaf: mode: HTML encoding: utf-8 # 禁用缓存 cache: false profiles: active: druid # mybatis 配置 mybatis: mapper-locations: classpath:mybatis/mappers/*.xml configuration: map-underscore-to-camel-case: true #驼峰转换 use-generated-keys: true #获取数据库自增列 use-column-label: true #使用列别名替换列名 log-impl: org.apache.ibatis.logging.stdout.StdOutImpl default-executor-type: reuse #配置默认的执行器 cache-enabled: true #全局映射器启用缓存 type-aliases-package: com.comet #实体类配置别名 application-druid.yml# 数据源配置 spring: datasource: type: com.alibaba.druid.pool.DruidDataSource driverClassName: com.mysql.jdbc.Driver druid: # 主库数据源 master: url: jdbc:mysql://192.168.1.20:3306/comet1?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 username: root password: root # 从库数据源 cluster: # 从数据源开关/默认关闭 enabled: true url: jdbc:mysql://192.168.1.21:3306/comet2?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 username: root password: root # 初始连接数 initialSize: 5 # 最小连接池数量 minIdle: 10 # 最大连接池数量 maxActive: 20 # 配置获取连接等待超时的时间 maxWait: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 timeBetweenEvictionRunsMillis: 60000 # 配置一个连接在池中最小生存的时间,单位是毫秒 minEvictableIdleTimeMillis: 300000 # 配置一个连接在池中最大生存的时间,单位是毫秒 maxEvictableIdleTimeMillis: 900000 # 配置检测连接是否有效 validationQuery: SELECT 1 FROM DUAL testWhileIdle: true testOnBorrow: false testOnReturn: false # 配置DruidStatFilter webStatFilter: enabled: true url-pattern: "/*" exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*" # 配置DruidStatViewServlet statViewServlet: enabled: true # 设置白名单,不填则允许所有访问 allow: url-pattern: /druid/* # 控制台管理用户名和密码 login-username: login-password: filter: stat: enabled: true # 慢SQL记录 log-slow-sql: true slow-sql-millis: 1000 merge-sql: true wall: config: multi-statement-allow: true代码枚举类 数据类型/** * @author Unclue_liu * @organization comet * @date 2019/9/3 0003 17:00 * @desc TODO 数据类型 */ public enum DataSourceType { /** * 主数据 */ MASTER, /** * 从数据 */ CLUSTER }注解类 自定义注解import com.comet.common.enums.DataSourceType; import java.lang.annotation.*; /** * @author Unclue_liu * @organization comet * @date 2019/9/3 0003 17:00 * @desc TODO 自定义多数据源切换注解,可以用于service类或者方法级别 方法级别优先级 > 类级别 */ @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited public @interface DataSource { /** * 切换数据源名称 */ DataSourceType value() default DataSourceType.MASTER; }druid 配置属性import com.alibaba.druid.pool.DruidDataSource; import lombok.Data; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; /** * @author Unclue_liu * @organization comet * @date 2019/10/18 0018 15:36 * @desc TODO druid 配置属性 */ @Data @Configuration public class DruidProperties { @Value("${spring.datasource.druid.initialSize}") private int initialSize; @Value("${spring.datasource.druid.minIdle}") private int minIdle; @Value("${spring.datasource.druid.maxActive}") private int maxActive; @Value("${spring.datasource.druid.maxWait}") private int maxWait; @Value("${spring.datasource.druid.timeBetweenEvictionRunsMillis}") private int timeBetweenEvictionRunsMillis; @Value("${spring.datasource.druid.minEvictableIdleTimeMillis}") private int minEvictableIdleTimeMillis; @Value("${spring.datasource.druid.maxEvictableIdleTimeMillis}") private int maxEvictableIdleTimeMillis; @Value("${spring.datasource.druid.validationQuery}") private String validationQuery; @Value("${spring.datasource.druid.testWhileIdle}") private boolean testWhileIdle; @Value("${spring.datasource.druid.testOnBorrow}") private boolean testOnBorrow; @Value("${spring.datasource.druid.testOnReturn}") private boolean testOnReturn; public DruidDataSource dataSource(DruidDataSource datasource) { /** 配置初始化大小、最小、最大 */ datasource.setInitialSize(initialSize); datasource.setMaxActive(maxActive); datasource.setMinIdle(minIdle); /** 配置获取连接等待超时的时间 */ datasource.setMaxWait(maxWait); /** 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 */ datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis); /** 配置一个连接在池中最小、最大生存的时间,单位是毫秒 */ datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis); datasource.setMaxEvictableIdleTimeMillis(maxEvictableIdleTimeMillis); /** * 用来检测连接是否有效的sql,要求是一个查询语句,常用select 'x'。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会起作用。 */ datasource.setValidationQuery(validationQuery); /** 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。 */ datasource.setTestWhileIdle(testWhileIdle); /** 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 */ datasource.setTestOnBorrow(testOnBorrow); /** 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 */ datasource.setTestOnReturn(testOnReturn); return datasource; } }数据源切换处理import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Unclue_liu * @organization comet * @date 2019/10/18 0018 15:36 * @desc TODO 数据源切换处理 */ public class DynamicDataSourceContextHolder { public static final Logger log = LoggerFactory.getLogger(DynamicDataSourceContextHolder.class); /** * CONTEXT_HOLDER代表一个可以存放String类型的ThreadLocal对象, * 此时任何一个线程可以并发访问这个变量, * 对它进行写入、读取操作,都是线程安全的。 * 比如一个线程通过CONTEXT_HOLDER.set(“aaaa”);将数据写入ThreadLocal中, * 在任何一个地方,都可以通过CONTEXT_HOLDER.get();将值获取出来。 * 这里写入的就是数据库名, */ private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>(); /** * 设置数据源的变量 */ public static void setDataSourceType(String dsType) { log.info("切换到{}数据源", dsType); CONTEXT_HOLDER.set(dsType); } /** * 获得数据源的变量 */ public static String getDataSourceType() { return CONTEXT_HOLDER.get(); } /** * 清空数据源变量 */ public static void clearDataSourceType() { CONTEXT_HOLDER.remove(); } }动态数据源import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; import javax.sql.DataSource; import java.util.Map; /** * @author Unclue_liu * @organization comet * @date 2019/10/18 0018 15:36 * @desc TODO 动态数据源 */ public class DynamicDataSource extends AbstractRoutingDataSource { public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources) { super.setDefaultTargetDataSource(defaultTargetDataSource); super.setTargetDataSources(targetDataSources); super.afterPropertiesSet(); } @Override protected Object determineCurrentLookupKey() { return DynamicDataSourceContextHolder.getDataSourceType(); } }druid 配置多数据源import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder; import com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties; import com.alibaba.druid.util.Utils; import com.comet.config.datasource.DynamicDataSource; import com.comet.common.enums.DataSourceType; import com.comet.config.properties.DruidProperties; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import javax.servlet.*; import javax.sql.DataSource; import java.io.IOException; import java.util.HashMap; import java.util.Map; /** * @author Unclue_liu * @organization comet * @date 2019/10/18 0018 15:36 * @desc TODO druid 配置多数据源 */ @Configuration public class DataSourceConfig { @Bean @ConfigurationProperties("spring.datasource.druid.master") public javax.sql.DataSource masterDataSource(DruidProperties druidProperties) { DruidDataSource dataSource = DruidDataSourceBuilder.create().build(); return druidProperties.dataSource(dataSource); } @Bean @ConfigurationProperties("spring.datasource.druid.cluster") @ConditionalOnProperty(prefix = "spring.datasource.druid.cluster", name = "enabled", havingValue = "true") public javax.sql.DataSource clusterDataSource(DruidProperties druidProperties) { DruidDataSource dataSource = DruidDataSourceBuilder.create().build(); return druidProperties.dataSource(dataSource); } @Bean(name = "dynamicDataSource") @Primary public DynamicDataSource dataSource(javax.sql.DataSource masterDataSource, DataSource clusterDataSource) { Map<Object, Object> targetDataSources = new HashMap<>(); targetDataSources.put(DataSourceType.MASTER.name(), masterDataSource); targetDataSources.put(DataSourceType.CLUSTER.name(), clusterDataSource); return new DynamicDataSource(masterDataSource, targetDataSources); } /** * 去除监控页面底部的广告 */ @SuppressWarnings({ "rawtypes", "unchecked" }) @Bean @ConditionalOnProperty(name = "spring.datasource.druid.statViewServlet.enabled", havingValue = "true") public FilterRegistrationBean removeDruidFilterRegistrationBean(DruidStatProperties properties) { // 获取web监控页面的参数 DruidStatProperties.StatViewServlet config = properties.getStatViewServlet(); // 提取common.js的配置路径 String pattern = config.getUrlPattern() != null ? config.getUrlPattern() : "/druid/*"; String commonJsPattern = pattern.replaceAll("\\*", "js/common.js"); final String filePath = "support/http/resources/js/common.js"; // 创建filter进行过滤 Filter filter = new Filter() { @Override public void init(javax.servlet.FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { chain.doFilter(request, response); // 重置缓冲区,响应头不会被重置 response.resetBuffer(); // 获取common.js String text = Utils.readFromResource(filePath); // 正则替换banner, 除去底部的广告信息 text = text.replaceAll("<a.*?banner\"></a><br/>", ""); text = text.replaceAll("powered.*?shrek.wang</a>", ""); response.getWriter().write(text); } @Override public void destroy() { } }; FilterRegistrationBean registrationBean = new FilterRegistrationBean(); registrationBean.setFilter(filter); registrationBean.addUrlPatterns(commonJsPattern); return registrationBean; } }多数据源处理import com.comet.common.annotation.DataSource; import com.comet.common.utils.StringUtils; import com.comet.config.datasource.DynamicDataSourceContextHolder; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import java.lang.reflect.Method; /** * @author Unclue_liu * @organization comet * @date 2019/10/18 0018 15:36 * @desc TODO 多数据源处理 */ @Aspect @Order(1) @Component public class DataSourceAspect { @Pointcut("@annotation(com.comet.common.annotation.DataSource)" + "|| @within(com.comet.common.annotation.DataSource)") public void dsPointCut() { } @Around("dsPointCut()") public Object around(ProceedingJoinPoint point) throws Throwable { DataSource dataSource = getDataSource(point); if (StringUtils.isNotNull(dataSource)) { DynamicDataSourceContextHolder.setDataSourceType(dataSource.value().name()); } try { return point.proceed(); } finally { // 销毁数据源 在执行方法之后 DynamicDataSourceContextHolder.clearDataSourceType(); } } /** * 获取需要切换的数据源 */ public DataSource getDataSource(ProceedingJoinPoint point) { MethodSignature signature = (MethodSignature) point.getSignature(); Class<? extends Object> targetClass = point.getTarget().getClass(); DataSource targetDataSource = targetClass.getAnnotation(DataSource.class); if (StringUtils.isNotNull(targetDataSource)) { return targetDataSource; } else { Method method = signature.getMethod(); DataSource dataSource = method.getAnnotation(DataSource.class); return dataSource; } } }至此多数据源配置完成。使用如果主从数据都使用,将从数据源改为true否则反之。这里配置druid的登录账户密码,如果没有配置则直接通过http://127.0.0.1/druid/index.html访问项目启动默认使用主数据源,如需切换从数据可使用如下方式:或
2021年12月08日
549 阅读
0 评论
0 点赞