springcloud项目是一个父工程+n多子工程的项目
所以这次来做个总结 也算个记录
先创建一个父工程
下一步
下面是pom的依赖
<!--打包成pom而不是jar-->
<packaging>pom</packaging>
<properties>
<!--动态的版本号 用${}来引用-->
<junit.version>4.12</junit.version>
<log4j.version>1.2.17</log4j.version>
<lombok.version>1.16.18</lombok.version>
</properties>
<!--依赖管理 父工程使用这个 子工程的依赖如果在父工程能够找到 则不需要添加版本号-->
<dependencyManagement>
<dependencies>
<dependency>
<!--最新版springcloud-->
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--springboot依赖 不需要全部-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.2.1.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--web项目需要的依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
<!--mybatis依赖-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.3</version>
</dependency>
<!--mysql 8以上的版本-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</version>
</dependency>
<!--德鲁伊 查看数据库监控信息-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.24</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>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<!--实用小工具-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
新建子模块
不用选 下一步
之后在pom添加依赖 由于父工程有 所以不需要版本号 这个工程主要是提供pojo类的
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
新建数据库 加一个表(自定义就好 不需要一样) 然后随便加点数据
对应的pojo类 注意 网络传输 一定要实现序列化
//无参构造
@NoArgsConstructor
//lombok自动写入get set方法
@Data
//链式写法
@Accessors(chain = true)
public class Dept implements Serializable {
/**
* 主键
*/
private Long deptno;
/**
* 部门名称
*/
private String dname;
private String db_source;
public Dept(String dname) {
this.dname = dname;
}
}
---
再建个子模块 生产者 最好写下端口 避免模块太多不知道端口号
pom依赖
<dependencies>
<!--主要是拿到api的pojo类-->
<dependency>
<artifactId>springcloud-api</artifactId>
<groupId>cn.bb</groupId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<!--web服务-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
yml文件
server:
port: 8001
spring:
datasource: #数据库配置
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/springcloud01?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai
#应用名称
application:
name: springcloud-provider
#mybatis 第一个是配置文件的位置 第二个是映射文件的名字 注意要与mapper类同名 注意文件夹位置
mybatis:#可以等到创建 mapper service后再写
config-location: classpath:mybatis/mybatis-config.xml
mapper-locations: classpath:mybatis/mapper/*Mapper.xml
Mapper类 就是dao层
public interface DeptMapper {
public boolean addDept(Dept dept); //添加一个部门
public Dept queryById(Long id); //根据id查询部门
public List<Dept> queryAll(); //查询所有部门
}
service接口
public interface DeptService {
public boolean addDept(Dept dept); //添加一个部门
public Dept queryById(Long id); //根据id查询部门
public List<Dept> queryAll(); //查询所有部门
}
接口实现类
@Service
public class DeptServiceImpl implements DeptService {
/**
* 自动注入
*/
@Autowired
private DeptMapper deptDao;
@Override
public boolean addDept(Dept dept) {
return deptDao.addDept(dept);
}
@
Override
public Dept queryById(Long id) {
return deptDao.queryById(id);
}
@
Override
public List<Dept> queryAll() {
return deptDao.queryAll();
}
}
控制层
@RestController
@RequestMapping("/dept")
public class DeptController {
@Autowired
private DeptService service;
@PostMapping("/add")
public boolean addDept(@RequestBody Dept dept) {
return service.addDept(dept);
}
@GetMapping("/get/{id}")
public Dept get(@PathVariable("id") Long id) {
return service.queryById(id);
}
@GetMapping("/list")
public List<Dept> queryAll() {
return service.queryAll();
}
}
接下里是mybatis的配置
mybatis-config.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
<?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="cn.bb.mapper.DeptMapper">
<insert id="addDept" parameterType="cn.bb.Dept">
insert into dept (dname,db_source) values (#{dname},DATABASE());
</insert>
<select id="queryById" resultType="cn.bb.Dept" parameterType="Long">
select deptno,dname,db_source from dept where deptno = #{deptno};
</select>
<select id="queryAll" resultType="cn.bb.Dept">
select deptno,dname,db_source from dept;
</select>
</mapper>
对了 还要建一个启动类
ProviderApplication
@MapperScan(“cn.bb.mapper”) 这个注解很重要 否则扫描不到mapper类
@SpringBootApplication
@MapperScan("cn.bb.mapper")
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
}
细节的地方可以对照修改一下
注意我的目录是这样的
启动项目 认准地址 否则就要出错
成功
这里没有演示post请求 因为不能直接在网址提交对应请求
接下里是消费者
pom文件
<dependencies>
<!--主要是拿到api的pojo类-->
<dependency>
<artifactId>springcloud-api</artifactId>
<groupId>cn.bb</groupId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--web服务-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
重点是 如何远程调用8001端口的生产者的方法
我们需要RestTemplate类 这个类是能够将生产者的get post接口给调用的方法
使用RestTemplate访问restful接口非常的简单粗暴且无脑
(url,requsetMap,ResponseBean.class) 这三个参数分别代表REST请求地址,请求参数,
Http响应转换 被 转换成的对象类型
但我们还需要一些配置
创建一个配置类 以便controller自动注入
@Configuration
public class ConfigBean {
@Bean
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
控制层远程调用
@RestController
@RequestMapping("/consumer")
public class Controller {
@Autowired
private RestTemplate restTemplate;
private static final String REST_URL_PREFIX = "http://localhost:8001";
@RequestMapping("/add")
public boolean add(Dept dept) {
return restTemplate.postForObject(REST_URL_PREFIX + "/dept/add", dept, Boolean.class);
}
@RequestMapping("/get/{id}")
public Dept get(@PathVariable("id") Long id) {
return restTemplate.getForObject(REST_URL_PREFIX + "/dept/get/" + id, Dept.class);
}
@RequestMapping("/list")
public List<Dept> list() {
return restTemplate.getForObject(REST_URL_PREFIX + "/dept/list", List.class);
}
}
大家可以看看RestTemplate 的一系列方法 参
如get请求就是用getForObject post用postForObject 就可以了
启动项目
接下来加入Erurka 提供服务注册与发现
三大角色
Eureka Server:提供服务的注册于发现。
Service Provider:将自身服务注册到Eureka中,从而使消费方能够找到。
Service Consumer:服务消费方从Eureka中获取注册服务列表,从而找到消费服务。
再建新的子模块
引入这一个依赖就可以了 这是eureak的服务端
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
yml文件的配置
server:
port: 7001
eureka:
instance:
hostname: localhost #eureka服务端的实例名称
client:
register-with-eureka: false #是否将自己注册到Eureka服务器中,本身是服务器,无需注册
fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
service-url:
# 设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个defaultZone地址
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
再加个启动来注解就完工啦 一定要加@EnableEurekaServer
@SpringBootApplication
//EurekaServer服务器端启动类,接受其他微服务注册进来!
@EnableEurekaServer
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class);
}
}
成功访问
System Status:系统信息
DS Replicas:服务器副本
Instances currently registered with Eureka:已注册的微服务列表
General Info:一般信息
Instance Info:实例信息
接下来可以将服务入驻了
在生产者的pom里添加eureka的依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
yml文件的新增配置
#eureka配置
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka
同时启动类加入**@EnableEurekaClient**
有了客户端 有了服务端 启动项目 要先启动7001服务端 再启动8001客户端
红字是正常现象 待会解释
默认情况下,如果EurekaServer在一定时间内没有接收到某个微服务实例的心跳,EurekaServer将会注销该实例(默认90秒)。
但是当网络分区故障发生时,微服务与Eureka之间无法正常通行,以上行为可能变得非常危险了
–因为微服务本身其实是健康的,此时本不应该注销这个服务。Eureka通过自我保护机制来解决这个问题
–当EurekaServer节点在短时间内丢失过多客户端时(可能发生了网络分区故
障),那么这个节点就会进入自我保护模式。
一旦进入该模式,EurekaServer就会保护服务注册表中的信息,不再删除服务注册表中的数据(也就是不会注销任何微服务)。
当网络故障恢复后,该EurekaServer节点会自动退出自我保护模式
接下来是集群 为什么需要集群 因为服务器老是容易出问题 那么就需要多台服务器来提高容错率
相当于复制一下7001的模块就好了 但是还需要改一些配置
新建两个子模块
其他东西复制7001就可以了 当然 启动类不能同名 需要小小修改一下
为了集群 我们需要windows域名映射
按照这个路径 编辑该文件
增加这三行
同时修改不同的yml文件
yml文件 7001
server:
port: 7001
eureka:
instance:
hostname: eureka7001.com
client:
register-with-eureka: false
fetch-registry: false
service-url: defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
yml文件 7002
server:
port: 7002
eureka:
instance:
hostname: eureka7002.com
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7003.com:7003/eureka/
yml文件 7003
server:
port: 7003
eureka:
instance:
hostname: eureka7003.com
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7001.com:7001/eureka/
启动三个注册中心 发现都能够互相发现 说明成功了
未完待续。。。