SpringCloud微服务框架
微服务SpringCloud架构简介
微服务化的核心就是将传统的一站式应用,根据业务拆分成一个一个的服务,彻底地去耦合,每个微服务提供单个的业务功能的服务,一个服务做一件事情,从技术角度去看就是一种小而独立的处理过程,类似进程的概念,能够自行单独启动或者销毁,拥有自己独立的数据库。
微服务与微服务架构的理解
微服务是服务的大小,它关注的是某一个点,是具体解决某一个问题、提供落地对应服务的一个服务应用
微服务优点 每个服务足够内聚,足够小,代码容易理解这样能够聚焦一个指定的业务功能或者业务需求开发简单,开发效率提供,一个服务可能就是专一的干一件事情。缺点 开发人员要处理分布式的服务杂性 运维难度大 部署依赖 通信成本大
架构的相关组件
服务注册与发现----配置中心管理
服务调用----服务网关
服务熔断----服务监控
负载均衡----全链路监控
服务降级----自动化部署监控
服务消息队列----服务定时任务操作
微服务技术栈 服务开发 服务配置与管理 服务注册与发现 服务调用 服务熔断器 负载均衡 服务接口调用 消息队列 服务配置中心管理 服务路由 API网关 服务监控
Dubbo与SpringCloud对比 SpringCloud拥有完整的微服务架构,支持Rest Riibon支持多种可插的序列化选择,不是RPC,支持多种语言,Eureka是服务注册,是负载均衡Ribbon+客户端Zull Zull+服务动态代理,配置服务config,是服务调用链监控Zull,是高可用,容错Hystrix+客户端Ribbon Dubbo拥有微服务,不支持RESTFul,是RPC,不支持多种语言,是服务注册,是客户端负载均衡,不是配置服务config 不是服务调用链监控Zull,否
SpringCloud微服务概述 SpringClou是基于SpringBoot提供了一整套的微服务,技术栈有服务注册与发现,服务配置中心,全链路监控,服务网关,负载均衡,熔断器等组件 SpringCloud为开发人员提供了一整套的分布式系统,包括配置管理,服务发现,断路器,路哟,微代理,事件总线,全局索,决策竞选,分布式会话等
SpringClou与SpringBoot比较
Springcloud官方地址
创建microservicecloud父工程所依赖的架包
<packaging>pom</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<junit.version>4.12</junit.version>
<log4j.version>1.2.17</log4j.version>
<lombok.version>1.16.18</lombok.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.5.9.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.0.4</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.31</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
创建microservicecloud-api子模块 创建microservicecloud-api子模块的pom依赖的架包
<dependencies><!-- 当前Module需要用到的jar包,按自己需求添加,如果父类已经包含了,可以不用写版本号 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
创建实体类
package com.yang.entity;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;
@SuppressWarnings("serial")
@NoArgsConstructor
@Data
@Accessors(chain=true)
public class Dept implements Serializable {
private Long deptno; //主键
private String dname; //部门名称
private String db_source;//来自那个数据库,因为微服务架构可以一个服务对应一个数据库,同一个信息被存储到不同数据库
public Dept(String dname)
{
super();
this.dname = dname;
}
}
创建microservicecloud-provider-dept-8001 服务提 供者 加载pom仓库库依赖
<dependencies>
<dependency>
<groupId>com.yang</groupId>
<artifactId>microservicecloud-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<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>
</dependency>
<!-- 修改后立即生效,热部署 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<dependency>
<groupId>com.yang</groupId>
<artifactId>microservicecloud-api</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
创建application.yml配置文件
server:
port: 8001
mybatis:
config-location: classpath:mybatis/mybatis.cfg.xml # mybatis配置文件所在路径
type-aliases-package: com.yang.entity # 所有Entity别名类所在包
mapper-locations:
- classpath:mybatis/mapper/**/*.xml # mapper映射文件
spring:
application:
name: microservicecloud-dept
datasource:
type: com.alibaba.druid.pool.DruidDataSource # 当前数据源操作类型
driver-class-name: org.gjt.mm.mysql.Driver # mysql驱动包
url: jdbc:mysql://localhost:3306/cloudDB01 # 数据库名称
username: root
password: root
dbcp2:
min-idle: 5 # 数据库连接池的最小维持连接数
initial-size: 5 # 初始化连接数
max-total: 5 # 最大连接数
max-wait-millis: 200 # 等待连接获取的最大超时时间
eureka:
client: #客户端注册进eureka服务列表内
service-url:
defaultZone: http://localhost:7001/eureka
# defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
instance:
instance-id: microservicecloud-dept8001
prefer-ip-address: true #访问路径可以显示IP地址
info:
app.name: atguigu-microservicecloud
company.name: www.atguigu.com
build.artifactId: $project.artifactId$
build.version: $project.version$
创建mybatis.cfg.xml配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="cacheEnabled" value="true" /><!-- 二级缓存开启 -->
</settings>
</configuration>
创建deptMapper配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yang.dao.DeptDao">
<select id="findById" resultType="Dept" parameterType="Long">
select deptno,dname,db_source from dept where deptno=#{deptno};
</select>
<select id="findAll" resultType="Dept">
select deptno,dname,db_source from dept;
</select>
<insert id="addDept" parameterType="Dept">
INSERT INTO dept(dname,db_source) VALUES(#{dname},DATABASE());
</insert>
</mapper>
创建DeptDao层
package com.yang.dao;
import com.yang.entity.Dept;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface DeptDao {
public boolean addDept(Dept dept);
public Dept findById(Long id);
public List<Dept> findAll();
}
创建service接口
package com.yang.service;
import com.yang.entity.Dept;
import java.util.List;
public interface DeptService {
public boolean add(Dept dept);
public Dept get(Long id);
public List<Dept> list();
}
service的实现接口impl
package com.yang.service.impl;
import com.yang.dao.DeptDao;
import com.yang.entity.Dept;
import com.yang.service.DeptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class DeptServiceImpl implements DeptService {
@Autowired
private DeptDao dao ;
@Override
public boolean add(Dept dept)
{
return dao.addDept(dept);
}
@Override
public Dept get(Long id)
{
return dao.findById(id);
}
@Override
public List<Dept> list()
{
return dao.findAll();
}
}
编写controller层
package com.yang.controler;
import com.yang.entity.Dept;
import com.yang.service.DeptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
public class DeptController {
@Autowired
private DeptService service;
@RequestMapping(value="/dept/add",method= RequestMethod.POST)
public boolean add(@RequestBody Dept dept)
{
return service.add(dept);
}
@RequestMapping(value="/dept/get/{id}",method=RequestMethod.GET)
public Dept get(@PathVariable("id") Long id)
{
return service.get(id);
}
@RequestMapping(value="/dept/list",method=RequestMethod.GET)
public List<Dept> list()
{
return service.list();
}
}
创建microservicecloud-customer-dept-8080 消费者
加载pom依赖
<dependencies>
<dependency>
<groupId>com.yang</groupId>
<artifactId>microservicecloud-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 修改后立即生效,热部署 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
创建配置类
RestTemplate
「RestTemplate」提供了多种便捷访问远程Http服务的方法, 是一种简单便捷的访问restful服务模板类,是Spring提供的用于访问Rest服务的客户端模板工具集,官网地址:https://docs.spring.io/spring-framework/docs/4.3.7.RELEASE/javadoc-api/org/springframework/web/client/RestTemplate.html,使用restTemplate访问restful接口非常的简单粗暴无脑。(url, requestMap, ResponseBean.class)这三个参数分别代表 REST请求地址、请求参数、HTTP响应转换被转换成的对象类型。
package com.yang.springcloud.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class ConfigBean
{
@Bean
public RestTemplate getRestTemplate()
{
return new RestTemplate();
}
}
创建controller层
package com.yang.springcloud.controller;
import com.yang.entity.Dept;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.List;
@RestController
public class DeptController_Consumer {
private static final String REST_URL_PREFIX = "http://localhost:8001";
@Autowired
private RestTemplate restTemplate;
@RequestMapping(value="/consumer/dept/add")
public boolean add(Dept dept)
{
return restTemplate.postForObject(REST_URL_PREFIX+"/dept/add", dept, Boolean.class);
}
@RequestMapping(value="/consumer/dept/get/{id}")
public Dept get(@PathVariable("id") Long id)
{
return restTemplate.getForObject(REST_URL_PREFIX+"/dept/get/"+id, Dept.class);
}
@SuppressWarnings("unchecked")
@RequestMapping(value="/consumer/dept/list")
public List<Dept> list()
{
return restTemplate.getForObject(REST_URL_PREFIX+"/dept/list", List.class);
}
}
创建启动类
package com.yang.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DeptConsumer80_App
{
public static void main(String[] args)
{
SpringApplication.run(DeptConsumer80_App.class, args);
}
}