尚筹网2-1.项目环境搭建

一、项目功能梳理

1.后台管理系统

  • 权限管理
    • 用户维护 √
    • 角色维护 √
    • 菜单维护 √
  • 业务审核
    • 实名认证审核
    • 广告审核
    • 项目审核 √

2.前台会员系统

  • 用户模块
  • 项目模块
  • 订单/支付模块

二、项目架构设计

了解或介绍一个项目架构的步骤:

  • 确定总体上是单一架构还是分布式架构
    • 单一架构
      • 数据库
      • 框架
      • 前端技术
      • 确定工程之间的关系
        • 继承关系(Maven提供)
        • 聚合关系(Maven提供)
        • 依赖关系(Maven提供)
    • 分布式架构
      • 确定Dubbo+Zookeeper还是SpringBoot+SpringCloud
      • 确定整个项目中有哪些工程
      • 确定工程之间的关系
        • 继承关系(Maven提供)
        • 聚合关系(Maven提供)
        • 依赖关系(Maven提供)
        • 调用关系(远程调用技术提供)
      • 每个工程的大致作用
      • 用到了哪些中间件(Redis、文件存储服务器、消息队列、搜索引擎……)

三、创建数据库

CREATE DATABASE `distributed-crowd` CHARACTER SET utf8 COLLATE utf8_bin;

四、项目工程创建

1.父工程

①坐标

groupId:com.rgh.crowd

artifactId:distribution-crowd-parent

packaging:<font color="blue"><b>pom</b></font>

②属性声明

<properties>
    <!-- SpringBoot -->
    <spring-boot.version>2.0.7.RELEASE</spring-boot.version>
    <!-- SpringCloud -->
    <spring-cloud.version>Finchley.SR2</spring-cloud.version>
    <!-- 公共依赖 -->
    <commons-io.version>2.5</commons-io.version>
    <commons-lang3.version>3.6</commons-lang3.version>
    <commons-codec.version>1.10</commons-codec.version>
    <commons-beanutils.version>1.9.3</commons-beanutils.version>
    <commons-collections.version>3.2.2</commons-collections.version>
    <commons-math3.version>3.6.1</commons-math3.version>
    <commons.fileupload>1.3.2</commons.fileupload>
    <commons-email.version>1.4</commons-email.version>
    <!-- junit -->
    <junit.version>4.12</junit.version>
    <!-- 时间日期操作 -->
    <joda-time.version>2.9.9</joda-time.version>
    <!-- httpclient -->
    <httpclient.version>4.5.3</httpclient.version>
    <!-- 功能组件 -->
    <poi.version>3.16</poi.version>
    <quartz.version>2.2.3</quartz.version>
    <!-- 数据库和数据库连接池 -->
    <druid.version>1.1.0</druid.version>
    <mysql.connector>5.1.42</mysql.connector>
    <!-- 基础框架 -->
    <spring.version>5.0.11.RELEASE</spring.version>
    <mybatis.spring.boot.starter>1.3.2</mybatis.spring.boot.starter>
    <!-- 分页 -->
    <pagehelper.version>5.0.3</pagehelper.version>
    <!-- jackson -->
    <jackson.version>2.9.8</jackson.version>
    <!-- MBG -->
    <mbg.version>1.3.5</mbg.version>
    <!-- 日志 -->
    <log4j.version>1.2.17</log4j.version>
    <slf4j.version>1.7.6</slf4j.version>
    <logback.version>1.2.3</logback.version>
    <!-- servlet-api,jsp-api,jstl -->
    <servlet-api.version>2.5</servlet-api.version>
    <jsp-api.version>2.2</jsp-api.version>
    <jstl.version>1.2</jstl.version>
</properties>

③依赖管理

<!-- 依赖管理 -->
<dependencyManagement>
    <dependencies>
        <!-- SpringBoot -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>${spring-boot.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <!-- SpringCloud -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <!-- 公共依赖 -->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>${commons-io.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>${commons-lang3.version}</version>
        </dependency>
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>${commons-codec.version}</version>
        </dependency>
        <dependency>
            <groupId>commons-beanutils</groupId>
            <artifactId>commons-beanutils</artifactId>
            <version>${commons-beanutils.version}</version>
        </dependency>
        <dependency>
            <groupId>commons-collections</groupId>
            <artifactId>commons-collections</artifactId>
            <version>${commons-collections.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-math3</artifactId>
            <version>${commons-math3.version}</version>
        </dependency>
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>${commons.fileupload}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-email</artifactId>
            <version>${commons-email.version}</version>
        </dependency>
        <!--公共依赖结束 -->
        <!-- junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>

        <!-- 时间日期 -->
        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
            <version>${joda-time.version}</version>
        </dependency>
        <!-- httpclient -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>${httpclient.version}</version>
        </dependency>
        <!-- jedis -->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.9.0</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.connector}</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>${druid.version}</version>
        </dependency>
        <!-- 基础框架 -->
        <!-- Spring配置 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc-portlet</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!-- mybatis配置 -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>${mybatis.spring.boot.starter}</version>
        </dependency>
        <!-- 基础框架完成 -->
        <!-- 分页 -->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>${pagehelper.version}</version>
        </dependency>
        <!-- jackson -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>${jackson.version}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>${jackson.version}</version>
        </dependency>
        <!-- MBG -->
        <dependency>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-core</artifactId>
            <version>${mbg.version}</version>
        </dependency>

        <!-- 日志 -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>${log4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <!-- 依赖的WEB类库 -->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>${jsp-api.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>${servlet-api.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>${jstl.version}</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>${logback.version}</version>
        </dependency>
    </dependencies>
</dependencyManagement>

2.公共模块工程

①坐标

groupId:com.rgh.crowd

artifactId:distribution-crowd-1-common

packaging:jar

②创建方式

建议通过Maven Module的方式创建子工程,好处是能够自动做好继承和聚合的配置。操作方法是在父工程上点右键→New→Maven Module

3.注册中心

①坐标

groupId:com.rgh.crowd

artifactId:distribution-crowd-2-registry-center

packaging:jar

[注:同样是Maven Module]

②依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

P.S.:当前工程的父工程(parent)已经通过import范围引入了SpringBoot和SpringCloud的依赖信息,所以当前工程不需要直接继承SpringBoot或SpringCloud。

③配置文件

application.yml

server:
  port: 1000
  
eureka:
  instance:
    hostname: registry-center
  client:
    register-with-eureka: false #自己就是注册中心,不用注册自己
    fetch-registry: false #不从其他注册中心取回服务地址
    service-url:
       defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

④主启动类

package com.rgh.crowd;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@EnableEurekaServer
@SpringBootApplication
public class CrowdMainType {
    public static void main(String[] args) {
        SpringApplication.run(CrowdMainType.class, args);
    }
}

4.数据库服务工程

①坐标

groupId:com.rgh.crowd

artifactId:distribution-crowd-3-database-provider

packaging:jar

[注:同样是Maven Module]

②依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

③配置文件

mybatis-config.xml

<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
</configuration>

application.yml

server:
  port: 2000
spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://192.168.56.200:3306/distributed-crowd?useSSL=false&useUnicode=true&characterEncoding=UTF-8
    driver-class-name: com.mysql.jdbc.Driver
  application:
    name: database-provider #当前微服务名称,注册服务信息时必须有
mybatis:
  config-location: classpath:mybatis/mybatis-config.xml
  mapper-locations: classpath:mybatis/mapper/*.xml
eureka:
  client:
    service-url:
      defaultZone: http://localhost:1000/eureka/
  instance:
    prefer-ip-address: true

④主启动类

// @EnableEurekaClient 专门针对Eureka注册中心
@EnableDiscoveryClient // 更为通用
@MapperScan("com.rgh.crowd.mapper") // 配置MyBatis的Mapper接口所在包进行自动扫描,配置了这个注解才能够将Mapper接口类型的bean注入Service。另外一种扫描Mapper的方法是在具体Mapper接口上使用@Mapper
@SpringBootApplication
public class CrowdMainType {
    public static void main(String[] args) {
        SpringApplication.run(CrowdMainType.class, args);
    }
}

@EnableEurekaClient 专门针对Eureka注册中心

@EnableDiscoveryClient 更为通用

@MapperScan("com.rgh.crowd.mapper") 配置MyBatis的Mapper接口所在包进行自动扫描,配置了这个注解才能够将Mapper接口类型的bean注入Service。另外一种扫描Mapper的方法是在具体Mapper接口上使用@Mapper

⑤获取数据库连接测试

@RunWith(SpringRunner.class)
@SpringBootTest
public class CrowdTest {
    @Autowired
    private DataSource dataSource;
    @Test
    public void testDataBaseConnection() throws SQLException {
        Connection connection = dataSource.getConnection();
        System.out.println(connection);
    }
}

使用基于SpringBoot提供的测试需要注意:测试类所在的包,也必须是主启动类所在包的子包,才能够享受到包的自动扫描——除非是在主启动类上使用了@ComponentScan注解明确指定了扫描的包。

⑥数据库连不上的可能原因

  • MySQL服务是否启动
  • IP地址是否正确
  • MySQL数据库名称是否正确
  • Linux防火墙是否关闭
  • 用户名、密码(如果数据库密码是以0开头的,则需要加引号)

5.Redis服务工程

①坐标

groupId:com.rgh.crowd

artifactId:distribution-crowd-4-redis-provider

packaging:jar

[注:同样是Maven Module]

②依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

③配置文件

server:
  port: 3000
spring:
  application:
    name: redis-provider
  redis:
    host: 192.168.56.150
eureka:
  client:
    service-url:
      defaultZone: http://localhost:1000/eureka/
  instance:
    prefer-ip-address: true

④主启动类

@EnableDiscoveryClient
@SpringBootApplication
public class CrowdMainType {
    public static void main(String[] args) {
        SpringApplication.run(CrowdMainType.class, args);
    }
}

⑤访问Redis测试

@Autowired
private RedisTemplate<Object, Object> redisTemplate;
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Test
public void testRedisTemplate() {
    redisTemplate.opsForValue().set("pig", "red");
}
@Test
public void testStringRedisTemplate() {
    stringRedisTemplate.opsForValue().set("newYear", "oleYear");
}

6.用户管理模块

①坐标

groupId:com.rgh.crowd

artifactId:distribution-crowd-5-member-manager

packaging:jar

[注:同样是Maven Module]

②依赖

用户管理模块不需要操作数据库,也不需要操作Redis,这些操作全部交给后面的Provider了,加入Web场景即可。而用户界面在前端工程展示,所以也不需要加入视图。

为了能够和Eureka注册中心交互还需要加入Eureka客户端。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

③配置文件

server:
  port: 4000
spring:
  application:
    name: member-manager

eureka:
  client:
    service-url:
      defaultZone: http://localhost:1000/eureka/
  instance:
    prefer-ip-address: true

④主启动类

@EnableDiscoveryClient
@SpringBootApplication
public class CrowdMainType {
    public static void main(String[] args) {
        SpringApplication.run(CrowdMainType.class, args);
    }
}

7.建立依赖关系

除了注册中心,database-provider、redis-provider和member-manager都需要依赖公共模块。

<dependency>
    <groupId>com.rgh.crowd</groupId>
    <artifactId>distribution-crowd-1-common</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

※Consumer调用Provider方式梳理

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,039评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,426评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,417评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,868评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,892评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,692评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,416评论 3 419
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,326评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,782评论 1 316
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,957评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,102评论 1 350
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,790评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,442评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,996评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,113评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,332评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,044评论 2 355

推荐阅读更多精彩内容