springcloud简单搭建

2020-04-08

引入:首先我们要了解什么是单体应用简单来说就是:所有功能放在一个 war/jar 文件内。

单体应用缺点:

1. 复杂性高:所有功能和代码混杂在一起,容易有 bug 隐患。
2. 技术债务高:导致后续开发很难修改和优化。
3. 部署频率低:每次都是全量部署,耗时长,风险大,迭代速度跟不上市场需求。
4. 可靠性差:任何一个功能出错,都会影响整个程序。
5. 扩展能力受限:不能根据业务模块进行伸缩扩展,操纵资源浪费。
6. 技术创新难:技术选型固定,很难引入新的框架或技术。

微服务(mico service):以开发一组小型服务(程序)的方式来开发一个独立的应用。

cluster(集群):多台服务器做相同的事情 。
distributed(分布式):多台服务器做不相同的事情,组合到一起是一个完整的程序。微服务程序就是典型的分布式程序。

采用微服务产生的问题

1. 拆分后的各个服务(service)之间如何互相发现(获取其他服务的位置ip)
2. 拆分后的各个服务(service)之间如何通信
3.客户端如何访问这么多的服务器-网关
4.服务挂了,怎么办

解决办法

1.使用 maven 聚合工程来把多个独立的微服务(maven项目)整合到一个 maven 项目中,方便开发和管理。

2.删除无用的 src 目录

20191015194052940.png

3.在 pom 文件中管理所有子项目都会使用的依赖

<?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>

    <!--springboot中添加提供相关的Maven默认依赖,让常用的包依赖可以省去version标签-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.8.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.laozhang</groupId>
    <artifactId>spring-cloud-test</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!--修改打包方式,项目的打包类型有:pom、jar、war。packaging默认是jar类型-->
    <packaging>pom</packaging>

    <dependencies>
        <!--springboot的web工程场景启动器-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--springboot测试场景启动器-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <properties>
        <!--默认使用Java8,可添加以下配置修改版本-->
        <java.version>1.8</java.version>
        <!--springcloud版本号-->
        <spring-cloud.version>Greenwich.SR3</spring-cloud.version>
    </properties>

    <!--一个依赖管理器,对cloud的依赖进行管理-->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</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>

4. 互相发现新建 Module 开发每个服务-eureka-server(注册中心)

2019101520011473.png

4.1 在注册中心的pom文件中增加注册中心的场景启动器:
<?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>spring-cloud-test</artifactId>
        <groupId>com.laozhang</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>eureka-server</artifactId>
    <dependencies>
        <!--服务注册中心场景启动器,这里暂时加一个就行-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>
</project>

4.2 创建 application 配置文件进行配置

20191015201711233.png

4.3 yml中
spring:
  profiles:
    active: dev #配置使用dev环境
4.4 在application-dev.yml中
spring:
  application:
    name: eureka-server    #程序名 = 服务名
server:
  port: 8761   #端口号
eureka:
  instance:
    hostname: localhost  #域名,在哪台服务器上运行就写那台的,  eureka-server
  client:
    register-with-eureka: false   #禁止在eureka-server注册自己,注册中心没必要再注册自己
    fetch-registry: false   #禁止在eureka-server注册自己,注册中心没必要再注册自己
    service-url:
      defaultZone:  http://${eureka.instance.hostname}:${server.port}/eureka  #在注册中心注册自己的地址

4.5 编写 springboot 启动类 EurekaServerApplication
4.6 为启动类增加 @EnableEurekaServer 注解
package com.laozhang;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

/**
 * @author zhangfan
 * @date 2019/10/15
 */
@SpringBootApplication
@EnableEurekaServer //注册中心启动类添加
public class EureakServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(EureakServerApplication.class,args);
    }
}
4.7 启动服务,访问注册中心的监控页面

http://localhost:8761
20191015202129505.png

5. user(用户服务)

5.1 依赖

<?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>spring-cloud-test</artifactId>
        <groupId>com.laozhang</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>user</artifactId>

    <!--添加单个服务(每个功能节点)的client场景启动器-->
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    </dependencies>

</project>

5.2 创建 application 配置文件进行配置,上边已经列举过,接下来我只展示dev中的配置:

spring:
  application:
    name:  user   #程序名 = 服务名
server:
  port: 8901 #端口号
eureka:
  client:
    service-url:
      defaultZone:  http://localhost:8761/eureka  #在注册中心注册自己的请求地址

5.3 编写 springboot 启动类 UserApplication

5.4 为启动类增加 @EnableEurekaClient 注解

package com.laozhang;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

/**
 * @author zhangfan
 * @date 2019/10/15
 */
@SpringBootApplication
@EnableEurekaClient //单个服务启动类添加的注解
public class UserApplication {

    public static void main(String[] args) {
        SpringApplication.run(UserApplication.class,args);
    }
}

5.5 创建 UserController 并编写 findAll 和 findById 方法

package com.laozhang.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author zhangfan
 * @date 2019/10/15
 */
@RestController
public class UserController {

    private String[] users = new String[]{"张三","李四","王五"};

    @GetMapping("/users")
    public String[] findAll(){
        return users;
    }

    @GetMapping("/users/{id}")
    public String findById(@PathVariable("id") Integer id){

        return id > 0 && id < 3 ? users[id] : "id错误";
    }
}

5.6 接下来再次访问这个网站,如图,已经有了一个服务

20191015204008396.png
访问如下网址,便有了数据
20191015204042770.png

6. 仿照上边的User,再编写一个food(菜品服务)

6.1 引入依赖,引入的依赖和User的完全相同

6.2 创建 application 配置文件进行配置,我只展示dev

spring:
  application:
    name: food   #程序名 = 服务名
server:
  port: 8902 #端口号
eureka:
  client:
    service-url:
      defaultZone:  http://localhost:8761/eureka  #在注册中心注册自己的请求地址

6.3 编写 springboot 启动类 FoodApplication

6.4 为启动类增加 @EnableEurekaClient 注解

6.5 编写controller代码,添加如下方法:

package com.laozhang.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author zhangfan
 * @date 2019/10/15
 */
@RestController
public class FoodController {
    private String[] users = new String[]{"水果","张","三"};

    @GetMapping("/foods")
    public String[] findAll(){
        return users;
    }

    @GetMapping("/foods/{id}")
    public String findById(@PathVariable("id") Integer id){

        return id > 0 && id < 3 ? users[id] : "id错误";
    }
}

7. zuul(网关/统一入口)

7.1 添加依赖

<?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>spring-cloud-test</artifactId>
        <groupId>com.laozhang</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>zuul</artifactId>

    <dependencies>
        <!--添加单个服务器的场景启动器-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!--为所有请求提供统一入口-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>
    </dependencies>

</project>

7.2 创建 application 配置文件进行配置

spring:
  application:
    name: zuul  #端口名=服务名
server:
  port: 8900  #设置统一的访问端口
eureka:
  client:
    service-url:
      defaultZone:  http://localhost:8761/eureka  #在注册中心注册自己的请求地址
zuul:
  routes: #配置路由(转发给哪个服务处理)信息
    user:  #自定义key,一般和要配置的服务名保持一致
      path:  /user-api/**  #客户端发送的请求地址
      serviceId:  user  #转发给哪个服务进行处理
    food:
      path: /food-api/**  #food 的就转发给food处理
      serviceId:  food    #转发给哪个服务进行处理

7.3 编写 springboot 启动类 ZuulApplication

7.4 为启动类增加 @EnableEurekaClient 和 @EnableZuulProxy 注解

package com.laozhang;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

/**
 * @author zhangfan
 * @date 2019/10/15
 */
@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
public class ZuulApplication {

    public static void main(String[] args) {
        SpringApplication.run(ZuulApplication.class,args);
    }
}

7.5 再次启动访问http://localhost:8761/ 会发现又多了一个
20191015211711550.png
这时我们就可以用一个端口8900访问user和food了,如图
20191015211828275.png
20191015211856211.png

8. 拆分后的各个服务(service)之间如何通信:

这里说两种解决方案,ribbon和feign


标题:springcloud简单搭建
作者:张范
地址:http://misterzhang.top/articles/2020/04/08/1586319726353.html