xx商城项目搭建
1. 技术找
SpringCloudAlibaba + SpringMVC + SpringBoot + VUE.js + Mybatis 3 + MySQL + Redis + Nacox + Nginx + FastDFS + RabbitMQ + Elasticsearch 等
2. 项目搭建
2.1. 项目介绍
xx商城是一个综合性的B2C商城,功能类似于淘宝、京东。用户可以在系统中通过搜索商品、查看商品详情、加入购物车、购买商品并生成订单完成购物操作。
动力优品共分为两部分:
商城后台管理系统:
主要实现对商品、商品分类、规格参数、CMS 等业务的处理。
商城前台系统:
主要提供用户通过访问首页,完成购物流程的处理。
2.2. 系统架构
![](https://img-blog.csdnimg.cn/img_convert/36a3248eb969b1712ffdd78c102b2b02.png)
2.3. 开发环境
为了保证开发环境的统一,希望每个人都按照我的环境来配置:
IDE:我们使用Idea
JDK:统一使用JDK1.8
项目构建:maven3.3.9以上版本即可(3.5.2)
版本控制工具:git
服务器:centos7
2.4. 工程搭建分析
xx_shop_parent:管理依赖的版本号
|-- common_pojo:pojo
|--common_utils:工具类
|--xx_shop_item:商品服务
2.5. 创建xx_shop_parent
创建统一的父工程:xx_parent,用来管理依赖及其版本,注意是创建project,而不是module
![](https://img-blog.csdnimg.cn/img_convert/2f9e8ac5d078d9875f55c0bd1afd6372.png)
不要选择骨架:
![](https://img-blog.csdnimg.cn/img_convert/60255e3df1e26ae7767abe0fb88f09fa.png)
填写项目信息和保存位置:
![](https://img-blog.csdnimg.cn/img_convert/df619ee9a16f85766a2fe1f95959b3f1.png)
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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.xxshop</groupId>
<artifactId>xx_shop_parent</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 自定义属性标签 -->
<properties>
<!-- 项目源码及编译输出的编码 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- 项目编译JDK版本 -->
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<spring-boot-version>2.3.2.RELEASE</spring-boot-version>
<spring-cloud-version>Hoxton.SR9</spring-cloud-version>
<spring-cloud-alibaba-version>2.2.6.RELEASE</spring-cloud-alibaba-version>
<mybatis-version>3.5.1</mybatis-version>
<mysql-connector-java-version>5.1.38</mysql-connector-java-version>
<druid-version>1.0.9</druid-version>
<pagehelper-version>1.2.10</pagehelper-version>
<logback-version>5.0</logback-version>
<spring-mybatis-version>2.0.1</spring-mybatis-version>
</properties>
<dependencyManagement>
<dependencies>
<!--Spring Boot-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--spring cloud Netflix-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--spring cloud 阿里巴巴-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- MyBatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis-version}</version>
</dependency>
<!-- MySql Driver -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-connector-java-version}</version>
</dependency>
<!--Alibaba DataBase Connection Pool-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid-version}</version>
</dependency>
<!--PageHelper-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>${pagehelper-version}</version>
</dependency>
<!--MyBatis And Spring Integration Starter-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${spring-mybatis-version}</version>
</dependency>
<!--Logback-->
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>${logback-version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<resources>
<!-- mapper.xml文件在java目录下 -->
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<!-- resources目录不变色 -->
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
</build>
</project>
2.5.1. 父工程的作用
为什么不在power-shop-parent定义所有jar包,而是定义版本号呢?
项目部署到tomcat需要打war包,如果这个项目依赖了所有的jar包则会非常大,导致传输非常慢
我们在父工程中锁定了SpringCloud等启动器的版本号,以后创建的子工程就不需要自己控制版本号了,方便升级。
可以删除src目录,工程结构如下:
![](https://img-blog.csdnimg.cn/img_convert/4c7c9894e78b0430eb86b813d16007bc.png)
2.6. 创建common_pojo子模块
2.6.1. 创建工程
选择新建module:
![](https://img-blog.csdnimg.cn/img_convert/459fdf46b1d1ac7e14900096462c74e5.png)
同样不要选择骨架:
![](https://img-blog.csdnimg.cn/img_convert/5791cc5f660588d0b4eb857dd2693fe1.png)
然后填写项目坐标,我们的项目名称为common_pojo:
![](https://img-blog.csdnimg.cn/img_convert/cd0234b93d4fcfd65d9899ce3872b186.png)
2.7. 创建 common_utils
与上面类似,选择maven方式创建Module,然后填写项目名称,我们命名为:common_utils
2.7.1. 创建工程
![](https://img-blog.csdnimg.cn/img_convert/ec9ed68e6429f02810e667f0f34b7d0d.png)
2.7.2. 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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>xx_shop_parent</artifactId>
<groupId>com.xxshop</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>common_utils</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
2.7.3.添加常用工具类
![](https://img-blog.csdnimg.cn/img_convert/56d99c7ae8eb08e8948f47065011f15c.png)
CookieUtils.java
/**
*
* Cookie 工具类
*
*/
public final class CookieUtils {
/**
* 得到Cookie的值, 不编码
*
* @param request
* @param cookieName
* @return
*/
public static String getCookieValue(HttpServletRequest request, String cookieName) {
return getCookieValue(request, cookieName, false);
}
/**
* 得到Cookie的值,
*
* @param request
* @param cookieName
* @return
*/
public static String getCookieValue(HttpServletRequest request, String cookieName, boolean isDecoder) {
Cookie[] cookieList = request.getCookies();
if (cookieList == null || cookieName == null) {
return null;
}
String retValue = null;
try {
for (int i = 0; i < cookieList.length; i++) {
if (cookieList[i].getName().equals(cookieName)) {
if (isDecoder) {
retValue = URLDecoder.decode(cookieList[i].getValue(), "UTF-8");
} else {
retValue = cookieList[i].getValue();
}
break;
}
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return retValue;
}
/**
* 得到Cookie的值,
*
* @param request
* @param cookieName
* @return
*/
public static String getCookieValue(HttpServletRequest request, String cookieName, String encodeString) {
Cookie[] cookieList = request.getCookies();
if (cookieList == null || cookieName == null) {
return null;
}
String retValue = null;
try {
for (int i = 0; i < cookieList.length; i++) {
if (cookieList[i].getName().equals(cookieName)) {
retValue = URLDecoder.decode(cookieList[i].getValue(), encodeString);
break;
}
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return retValue;
}
/**
* 设置Cookie的值 不设置生效时间默认浏览器关闭即失效,也不编码
*/
public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
String cookieValue) {
setCookie(request, response, cookieName, cookieValue, -1);
}
/**
* 设置Cookie的值 在指定时间内生效,但不编码
*/
public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
String cookieValue, int cookieMaxage) {
setCookie(request, response, cookieName, cookieValue, cookieMaxage, false);
}
/**
* 设置Cookie的值 不设置生效时间,但编码
*/
public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
String cookieValue, boolean isEncode) {
setCookie(request, response, cookieName, cookieValue, -1, isEncode);
}
/**
* 设置Cookie的值 在指定时间内生效, 编码参数
*/
public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
String cookieValue, int cookieMaxage, boolean isEncode) {
doSetCookie(request, response, cookieName, cookieValue, cookieMaxage, isEncode);
}
/**
* 设置Cookie的值 在指定时间内生效, 编码参数(指定编码)
*/
public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
String cookieValue, int cookieMaxage, String encodeString) {
doSetCookie(request, response, cookieName, cookieValue, cookieMaxage, encodeString);
}
/**
* 删除Cookie带cookie域名
*/
public static void deleteCookie(HttpServletRequest request, HttpServletResponse response,
String cookieName) {
doSetCookie(request, response, cookieName, "", -1, false);
}
/**
* 设置Cookie的值,并使其在指定时间内生效
*
* @param cookieMaxage cookie生效的最大秒数
*/
private static final void doSetCookie(HttpServletRequest request, HttpServletResponse response,
String cookieName, String cookieValue, int cookieMaxage, boolean isEncode) {
try {
if (cookieValue == null) {
cookieValue = "";
}
if (isEncode) {
cookieValue = URLEncoder.encode(cookieValue, "utf-8");
}
Cookie cookie = new Cookie(cookieName, cookieValue);
if (cookieMaxage > 0)
cookie.setMaxAge(cookieMaxage);
if (null != request) {// 设置域名的cookie
String domainName = getDomainName(request);
// System.out.println(domainName);
if (!"localhost".equals(domainName)) {
//cookie.setDomain(domainName);
}
}
cookie.setPath("/");
response.addCookie(cookie);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 设置Cookie的值,并使其在指定时间内生效
*
* @param cookieMaxage cookie生效的最大秒数
*/
private static final void doSetCookie(HttpServletRequest request, HttpServletResponse response,
String cookieName, String cookieValue, int cookieMaxage, String encodeString) {
try {
if (cookieValue == null) {
cookieValue = "";
} else {
cookieValue = URLEncoder.encode(cookieValue, encodeString);
}
Cookie cookie = new Cookie(cookieName, cookieValue);
if (cookieMaxage > 0)
cookie.setMaxAge(cookieMaxage);
if (null != request) {// 设置域名的cookie
String domainName = getDomainName(request);
// System.out.println(domainName);
if (!"localhost".equals(domainName)) {
cookie.setDomain(domainName);
}
}
cookie.setPath("/");
response.addCookie(cookie);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 得到cookie的域名
*/
private static final String getDomainName(HttpServletRequest request) {
String domainName = null;
String serverName = request.getRequestURL().toString();
if (serverName == null || serverName.equals("")) {
domainName = "";
} else {
// http://www.baidu.com/aaa/bb/ccc
// www.baidu.com.cn
serverName = serverName.toLowerCase();
if (serverName.startsWith("http://")){
serverName = serverName.substring(7);
} else if (serverName.startsWith("https://")){
serverName = serverName.substring(8);
}
final int end = serverName.indexOf(":");
System.out.println(end+" end......");
serverName = serverName.substring(0, end);
System.out.println(serverName+" Server........");
final String[] domains = serverName.split("\\.");
int len = domains.length;
if (len > 3) {
// www.xxx.com.cn
domainName = domains[len - 3] + "." + domains[len - 2] + "." + domains[len - 1];
} else if (len <= 3 && len > 1) {
// xxx.com or xxx.cn
domainName = domains[len - 2] + "." + domains[len - 1];
} else {
domainName = serverName;
}
}
if (domainName != null && domainName.indexOf(":") > 0) {
String[] ary = domainName.split("\\:");
domainName = ary[0];
}
return domainName=serverName;
}
}
IDUtils.java
/**
* 各种id生成策略
* @version 1.0
*/
public class IDUtils {
/**
* 图片名生成
*/
public static String genImageName() {
// 取当前时间的长整形值包含毫秒
long millis = System.currentTimeMillis();
// long millis = System.nanoTime();
// 加上三位随机数
Random random = new Random();
// 返回0~999的数据.
int end3 = random.nextInt(999);
// 如果不足三位前面补0. %d - 模拟C语言中的数学占位符. 03代表必须三位数字,不足三位使用0补齐.
String str = millis + String.format("%03d", end3);
return str;
}
/**
* 商品id生成
*/
public static long genItemId() {
//取当前时间的长整形值包含毫秒
long millis = System.currentTimeMillis();
//long millis = System.nanoTime();
//加上两位随机数
Random random = new Random();
int end2 = random.nextInt(99);
//如果不足两位前面补0
String str = millis + String.format("%02d", end2);
long id = new Long(str);
return id;
}
public static void main(String[] args) {
for(int i=0;i< 100;i++)
System.out.println(genItemId());
}
}
JsonUtils.java
/**
* 百战商城自定义响应结构
*/
public class JsonUtils {
// 定义jackson对象
private static final ObjectMapper MAPPER = new ObjectMapper();
/**
* 将对象转换成json字符串。
* <p>Title: pojoToJson</p>
* <p>Description: </p>
* @param data
* @return
*/
public static String objectToJson(Object data) {
try {
String string = MAPPER.writeValueAsString(data);
return string;
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return null;
}
/**
* 将json结果集转化为对象
*
* @param jsonData json数据
* @param beanType 对象中的object类型
* @return
*/
public static <T> T jsonToPojo(String jsonData, Class<T> beanType) {
try {
T t = MAPPER.readValue(jsonData, beanType);
return t;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 将json数据转换成pojo对象list
* <p>Title: jsonToList</p>
* <p>Description: </p>
* @param jsonData
* @param beanType
* @return
*/
public static <T>List<T> jsonToList(String jsonData, Class<T> beanType) {
JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType);
try {
List<T> list = MAPPER.readValue(jsonData, javaType);
return list;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static Map jsonToMap(String jsonData,Class beanType){
JavaType javaType = MAPPER.getTypeFactory().constructParametricType(Map.class,String.class,beanType);
try{
Map map = MAPPER.readValue(jsonData, javaType);
return map;
}catch(Exception e){
e.printStackTrace();
}
return null;
}
}
MD5Utils.java
/**
* MD5加密工具
*/
public class MD5Utils {
public static String digest(String source){
try{
MessageDigest digest = MessageDigest.getInstance("MD5");
byte[] temp = digest.digest(source.getBytes());
StringBuilder builder = new StringBuilder("");
for(byte b : temp){
String s = Integer.toHexString(0xFF & b);
if(s.length() == 1){
s = "0" + s;
}
builder.append(s);
}
return builder.toString();
}catch(Exception e){
return null;
}
}
}
PageResult.java
/**
* 分页模型
*/
public class PageResult implements Serializable {
private Integer pageIndex; //当前页
private Integer totalPage; //总页数
private List result; //结果集
public PageResult() {
}
public PageResult(Integer pageIndex, Integer totalPage, List result) {
this.pageIndex = pageIndex;
this.totalPage = totalPage;
this.result = result;
}
public Integer getPageIndex() {
return pageIndex;
}
public void setPageIndex(Integer pageIndex) {
this.pageIndex = pageIndex;
}
public Integer getTotalPage() {
return totalPage;
}
public void setTotalPage(Integer totalPage) {
this.totalPage = totalPage;
}
public List getResult() {
return result;
}
public void setResult(List result) {
this.result = result;
}
Result.java
/**
* 商城自定义响应模型
*/
public class Result implements Serializable {
// 定义jackson对象
private static final ObjectMapper MAPPER = new ObjectMapper();
// 响应业务状态
private Integer status;
// 响应消息
private String msg;
private static final Integer okcode=200;
private static final Integer errorcode=500;
// 响应中的数据
private Object data;
public static Result build(Integer status, String msg, Object data) {
return new Result(status, msg, data);
}
public static Result error( String msg) {
return new Result(500, msg, null);
}
public static Result ok(Object data) {
return new Result(data);
}
public static Result ok() {
return new Result(null);
}
public Result() {
}
public static Result build(Integer status, String msg) {
return new Result(status, msg, null);
}
public Result(Integer status, String msg, Object data) {
this.status = status;
this.msg = msg;
this.data = data;
}
public Result(Object data) {
this.status = okcode;
this.msg = "OK";
this.data = data;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
/**
* 将json结果集转化为EgoResult对象
*
* @param jsonData json数据
* @param clazz EgoResult中的object类型
* @return
*/
public static Result formatToPojo(String jsonData, Class<?> clazz) {
try {
if (clazz == null) {
return MAPPER.readValue(jsonData, Result.class);
}
JsonNode jsonNode = MAPPER.readTree(jsonData);
JsonNode data = jsonNode.get("data");
Object obj = null;
if (clazz != null) {
if (data.isObject()) {
obj = MAPPER.readValue(data.traverse(), clazz);
} else if (data.isTextual()) {
obj = MAPPER.readValue(data.asText(), clazz);
}
}
return build(jsonNode.get("status").intValue(), jsonNode.get("msg").asText(), obj);
} catch (Exception e) {
return null;
}
}
/**
* 没有object对象的转化
*
* @param json
* @return
*/
public static Result format(String json) {
try {
return MAPPER.readValue(json, Result.class);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* Object是集合转化
*
* @param jsonData json数据
* @param clazz 集合中的类型
* @return
*/
public static Result formatToList(String jsonData, Class<?> clazz) {
try {
JsonNode jsonNode = MAPPER.readTree(jsonData);
JsonNode data = jsonNode.get("data");
Object obj = null;
if (data.isArray() && data.size() > 0) {
obj = MAPPER.readValue(data.traverse(),
MAPPER.getTypeFactory().constructCollectionType(List.class, clazz));
}
return build(jsonNode.get("status").intValue(), jsonNode.get("msg").asText(), obj);
} catch (Exception e) {
return null;
}
}
/**
* 将字符串转换为对象,不包含Result内容
*
* @param jsonData json数据
* @param clazz 集合中的类型
* @return
*/
public static Result formatObjectToList(String jsonData, Class<?> clazz) {
try {
JsonNode jsonNode = MAPPER.readTree(jsonData);
Object obj= null;
if (jsonNode.isArray() && jsonNode.size() > 0) {
obj = MAPPER.readValue(jsonNode.traverse(),
MAPPER.getTypeFactory().constructCollectionType(List.class, clazz));
}
return build(null,null, obj);
} catch (Exception e) {
return null;
}
}
}
2.8. 创建power_shop_item
2.8.2. 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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>xx_shop</artifactId>
<groupId>com.xxshop</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>power_item</artifactId>
<?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>xx_shop_parent</artifactId>
<groupId>com.xxshop</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>xx_shop_item</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- MyBatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</dependency>
<!-- MySql Driver -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--Alibaba DataBase Connection Pool-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<!--PageHelper-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
</dependency>
<!--MyBatis And Spring Integration Starter-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
</dependencies>
</project>
2.8.3. application.yml
spring:
application:
name: power_shop_item
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/xx_shop?characterEncoding=UTF-8
username: root
password: 1111
type: com.alibaba.druid.pool.DruidDataSource
cloud:
nacos:
discovery:
server-addr: 192.168.153.129:8848
server:
port: 8090
2.8.4. logback.xml
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
<property name="LOG_HOME" value="${catalina.base:-.}/logs/" />
<!-- 控制台输出 -->
<appender name="Stdout" class="ch.qos.logback.core.ConsoleAppender">
<!-- 日志输出编码 -->
<layout class="ch.qos.logback.classic.PatternLayout">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
</pattern>
</layout>
</appender>
<!-- 按照每天生成日志文件 -->
<appender name="RollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志文件输出的文件名-->
<FileNamePattern>${LOG_HOME}/server.%d{yyyy-MM-dd}.log</FileNamePattern>
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
</pattern>
</layout>
<!--日志文件最大的大小-->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>10MB</MaxFileSize>
</triggeringPolicy>
</appender>
<!--myibatis log configure-->
<!-- 日志输出级别 -->
<root level="DEBUG">
<appender-ref ref="Stdout" />
<appender-ref ref="RollingFile" />
</root>
<!--日志异步到数据库 -->
<!-- <appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
日志异步到数据库
<connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">
连接池
<dataSource class="com.mchange.v2.c3p0.ComboPooledDataSource">
<driverClass>com.mysql.jdbc.Driver</driverClass>
<url>jdbc:mysql://127.0.0.1:3306/databaseName</url>
<user>root</user>
<password>root</password>
</dataSource>
</connectionSource>
</appender> -->
</configuration>
2.8.5. 创建启动类
@SpringBootApplication
@EnableDiscoveryClient
@MapperScan("com.xxshop.mapper")
public class PowerShopItemApp {
public static void main(String[] args) {
SpringApplication.run(PowerShopItemApp.class, args);
}
}
4. Nacos安装和启动
4.1. 下载
4.2. 安装
上传并解压安装包:
[root@localhost ~]# cd /usr/upload
[root@localhost upload]# tar -zxvf nacos-server-1.4.1.tar.gz -C /usr/local
4.3. 启动和关闭
启动:
[root@localhost local]# cd nacos/bin/
[root@localhost bin]# ./startup.sh -m standalone #非集群模式启动
... ...
nacos is starting with standalone
nacos is starting,you can check the /usr/java/nacos/logs/start.out
关闭:
[root@localhost bin]# ./shutdown.sh
The nacosServer(3543) is running...
Send shutdown request to nacosServer(3543) OK
[root@localhost bin]
5. Nacos开机自启
5.1. 编写开机启动文件
添加nacos.service文件
vim /lib/systemd/system/nacos.service #/lib/systemd/system存放启动文件目录
文件内容如下:
[Unit]
Description=nacos
After=network.target
[Service]
Type=forking
ExecStart=/usr/local/nacos/bin/startup.sh -m standalone
ExecReload=/usr/local/nacos/bin/shutdown.sh
ExecStop=/usr/local/nacos/bin/shutdown.sh
PrivateTmp=true
[Install]
WantedBy=multi-user.target
5.2. 修改nacos的startup.sh
修改JAVA_HOME路径,如下:
[ ! -e "$JAVA_HOME/bin/java" ] && JAVA_HOME=/usr/local/jdk1.8.0_191
5.3. 设置开机启动
systemctl daemon-reload #重新加载所有service文件
systemctl enable nacos.service #设置为开机启动
systemctl is-enabled nacos.service #查看该服务是否开机启动
systemctl start nacos.service #启动nacos服务
systemctl stop nacos.service #停止nacos服务
systemctl status nacos.service #查看该服务状态