SpringCloud
微服务技术栈有哪些!!
SpringClooud入门概述
什么是SpringCloud
学习springCloud的网址
<?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>springCloud</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>springCloudApi</artifactId>
<!--当前module自己需要的依赖,如果父类写了版本,这里就不需要版本-->
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
</dependencies>
</project>
package com.ljh.springCloud.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)//链式写法
public class Dept implements Serializable {//Dept实体类 orm 列表关系映射
private Long deptno;//主键
private String dname;
//这个数据数存在那个数据库的字段~微服务,一个服务对应一个数据库,同一个信息可能存在不同的数据库
private String db_source;
/*
链式写法:
Dept dept = new Dept();
dept.setDeptno("").setDname().set...
*/
}
package com.ljh.springcloud.controller;
import com.ljh.springCloud.pojo.Dept;
import com.ljh.springcloud.service.DeptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
//提供restful接口
@RestController
public class DeptController {
@Autowired
private DeptService deptService;
@Autowired
private DiscoveryClient discoveryClient;
@PostMapping("/dept/add")
public boolean addDept(Dept dept){
return deptService.addDept(dept);
}
@GetMapping("/dept/get/{id}")
public Dept queryById(@PathVariable("id") Long id){
return deptService.queryById(id);
}
@GetMapping("/dept/all")
public List<Dept> all(){
return deptService.queryList();
}
//注册进来的微服务~,获取一些消息
@GetMapping("/dept/discovery")
public Object discovery(){
//获取微服务列表的清单
List<String> services = discoveryClient.getServices();
System.out.println(services);
//得到一个具体微服务信息,通过具体的微服务id,applicationName
List<ServiceInstance> instances = discoveryClient.getInstances("SPRINGCLOUD-PROVIDER-DEPT");
for (ServiceInstance instance : instances) {
System.out.println(
instance.getHost()+"\t"+
instance.getPort()+"\t"+
instance.getUri()+"\t"+
instance.getServiceId()
);
}
return this.discoveryClient;
}
}
package com.ljh.springcloud.dao;
import com.ljh.springCloud.pojo.Dept;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
import java.util.List;
@Mapper
@Repository
public interface DeptDao {
public boolean addDept(Dept dept);
public Dept queryById(Long id);
public List<Dept> queryList();
}
package com.ljh.springcloud.service;
import com.ljh.springCloud.pojo.Dept;
import java.util.List;
public interface DeptService {
public boolean addDept(Dept dept);
public Dept queryById(Long id);
public List<Dept> queryList();
}
package com.ljh.springcloud.service;
import com.ljh.springCloud.pojo.Dept;
import com.ljh.springcloud.dao.DeptDao;
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 deptDao;
public boolean addDept(Dept dept) {
return deptDao.addDept(dept);
}
public Dept queryById(Long id) {
return deptDao.queryById(id);
}
public List<Dept> queryList() {
return deptDao.queryList();
}
}
package com.ljh.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
//启动类
@SpringBootApplication
@EnableEurekaClient//在服务启动后自动注册到Eureka中
public class DeptProvider_8001 {
public static void main(String[] args) {
SpringApplication.run(DeptProvider_8001.class,args);
}
}
<?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">
<!--nameSpace绑定一个对应的Dao/Mapper接口-->
<mapper namespace="com.ljh.springcloud.dao.DeptDao">
<select id="queryList" resultType="Dept">
select * from dept
</select>
<select id="queryById" parameterType="Long" resultType="Dept">
select * from dept where deptno = #{deptno}
</select>
<insert id="addDept" parameterType="Dept">
insert into dept (dname,db_source) values (#{dname},DATABASE())
</insert>
</mapper>
<?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核心配置文件-->
<configuration>
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
</configuration>
<dependencies>
<!--EUREKA-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
<!--actuator完善信息-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--我们需要拿到实体类,所以要配置api module-->
<dependency>
<groupId>org.example</groupId>
<artifactId>springCloudApi</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--junit-->
<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-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--jetty-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<!--热部署工具-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
server:
port: 8001
#Mybatis配置
mybatis:
config-location: classpath:mybatis/mybatis-config.xml
mapper-locations: classpath:mybatis/mapper/*.xml
type-aliases-package: com.ljh.springCloud.pojo
#spring的配置
spring:
application:
name: springcloud-provider-dept #三个服务名称一致
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: org.gjt.mm.mysql.Driver
url: jdbc:mysql://localhost:3306/db01?userUnicode=true&characterEncoding=utf-8
username: root
password: 123456
#Euraka的配置
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/,http://localhost:7003/eureka/
instance:
instance-id: springcloud-provider-dept8001 #修改eureka上的默认描述信息
#info配置
info:
app.name: ljh-springcloud
company.name: toec
<!--实体类+web-->
<dependencies>
<!--Ribbon-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
<!--Eureka-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.example</groupId>
<artifactId>springCloudApi</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--热部署工具-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
server:
port: 80
eureka:
client:
register-with-eureka: false #不向Eureka注册自己
service-url:
defaultZone: http://localhost:7001/eureka,http://localhost:7002/eureka,http://localhost:7003/eureka
#Eureka配置
package com.ljh.springcloud.config;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class ConfigBean {//@Configuration spring application.xml
//配置负载均衡实现RestTemplate
//IRule
//RoundRobinRule 轮询
//RandomRule 随机
// AvailabilityFilteringRule:会先过滤掉,跳闸的服务~
//RetryRule :会先按照轮询获取服务~如果服务获取失败,则会在指定时间内,重试
@Bean
@LoadBalanced//Ribbon
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
@Bean
public IRule myRule(){
return new RandomRule();
}
}
package com.ljh.springcloud.controller;
import com.ljh.springCloud.pojo.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 DeptConsumerController {
//理解:消费者,不应该有service层~
//RestTemplate....供我们直接调用就可以了!注册到spring中
//{url,实体:Map,Class<T> responseType}
@Autowired
private RestTemplate restTemplate;//提供多种便捷访问远程http服务的方法,简单的Restful服务模板
//Ribbon,我们这里的地址,应该是一个变量,通过服务名来访问
private static final String REST_URL_PREFIX="http://SPRINGCLOUD-PROVIDER-DEPT";
@RequestMapping("/consumer/dept/get/{id}")
public Dept get(@PathVariable("id") Long id){
return restTemplate.getForObject(REST_URL_PREFIX+"/dept/get/"+id,Dept.class);
}
@RequestMapping("/consumer/dept/add")
public boolean get(Dept dept){
return restTemplate.postForObject(REST_URL_PREFIX+"/dept/add",dept,Boolean.class);
}
@RequestMapping("/consumer/list")
public List<Dept> get(){
return restTemplate.getForObject(REST_URL_PREFIX+"/dept/all",List.class);
}
}
package com.ljh.springcloud;
import com.ljh.myRule.LjhRule;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
//Ribbon和 Eureka 整合以后,客户端可以直接调用,不用关心IP地址和端口号
@SpringBootApplication
@EnableEurekaClient
@RibbonClient(name="SPRINGCLOUD-PROVIDER-DEPT",configuration = LjhRule.class)
public class DeptConsumer_80 {
public static void main(String[] args) {
SpringApplication.run(DeptConsumer_80.class,args);
}
}
Eureka
Ribbon
Feign
Hystrix
服务降级
<!--
服务熔断:服务端~某个服务超时或者异常,引起熔断~保险丝
服务降级:客户端~ 从整体网站请求负载考虑~,当某个服务熔断或者关闭之后,服务将不再被调用~
此时在客户端,我们可以准备一个FallbackFactory,返回一个默认的值(缺省值),整体的服务水平下降了~但是,好歹能用~
-->
服务监控
说明:
这是流监控手动写代码
Zuul路由网关
SpringCloud config分布式配置
服务端连接Git配置
客户端连接服务端访问