此链接可查看springCloud详细信息https://docs.qq.com/doc/BRf85Y33IMg43FMZBB3GJqp93QkUjt1e0mHr2IQmKC2Cjyb92ATX7q2MRDz90SXiBi1Vci1K1
如果你看完了这篇文章,那么下面你只需要按步骤搭建项目就可以运行起整个springCloud了
1.首先搭建四个maven项目(名字如下,运行步骤也写好了)
2.pom依赖
01. microservicecloud(父工程依赖)
4.0.0
com.atguigu.springcloud
microservicecloud
0.0.1-SNAPSHOT
pom
UTF-8
1.8
1.8
4.12
1.2.17
1.16.18
org.springframework.cloud
spring-cloud-dependencies
Dalston.SR1
pom
import
org.springframework.boot
spring-boot-dependencies
1.5.9.RELEASE
pom
import
mysql
mysql-connector-java
5.0.4
com.alibaba
druid
1.0.31
org.mybatis.spring.boot
mybatis-spring-boot-starter
1.3.0
ch.qos.logback
logback-core
1.2.3
junit
junit
${junit.version}
test
log4j
log4j
${log4j.version}
microservicecloud
src/main/resources
true
org.apache.maven.plugins
maven-resources-plugin
$
microservicecloud-api
microservicecloud-provider-dept-8001
microservicecloud-consumer-dept-80
microservicecloud-eureka-7001
02. microservicecloud-api (公共子模块)
4.0.0
com.atguigu.springcloud
microservicecloud
0.0.1-SNAPSHOT
microservicecloud-api
org.projectlombok
lombok
org.springframework.cloud
spring-cloud-starter-feign
02-1.Java代码
package com.atguigu.springcloud.service;
import java.util.List;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.atguigu.springcloud.entities.Dept;
/**
*
* @Description: 修改microservicecloud-api工程,根据已经有的DeptClientService接口
*
* 新建
*
* 一个实现了FallbackFactory接口的类DeptClientServiceFallbackFactory
* @author zzyy
* @date 2018年4月21日
*/
//@FeignClient(value = "MICROSERVICECLOUD-DEPT")
@FeignClient(value = "MICROSERVICECLOUD-DEPT", fallbackFactory = DeptClientServiceFallbackFactory.class)
public interface DeptClientService {
@RequestMapping(value = "/dept/get/{id}", method = RequestMethod.GET)
public Dept get(@PathVariable("id") long id);
@RequestMapping(value = "/dept/list", method = RequestMethod.GET)
public List list();
@RequestMapping(value = "/dept/add", method = RequestMethod.POST)
public boolean add(Dept dept);
}
package com.atguigu.springcloud.service;
import java.util.List;
import org.springframework.stereotype.Component;
import com.atguigu.springcloud.entities.Dept;
import feign.hystrix.FallbackFactory;
@Component // 不要忘记添加,不要忘记添加
public class DeptClientServiceFallbackFactory implements FallbackFactory {
@Override
public DeptClientService create(Throwable throwable) {
return new DeptClientService() {
@Override
public Dept get(long id) {
return new Dept().setDeptno(id).setDname("该ID:" + id + "没有没有对应的信息,Consumer客户端提供的降级信息,此刻服务Provider已经关闭")
.setDb_source("no this database in MySQL");
}
@Override
public List list() {
return null;
}
@Override
public boolean add(Dept dept) {
return false;
}
};
}
}
com.atguigu.springcloud.entities 实体类
package com.atguigu.springcloud.entities;
import java.io.Serializable;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@NoArgsConstructor
//@AllArgsConstructor
@Data
@Accessors(chain = true)
public class Dept implements Serializable// entity --orm--- db_table
{
/**
*
*/
private static final long serialVersionUID = 1L;
private Long deptno; // 主键
private String dname; // 部门名称
private String db_source;// 来自那个数据库,因为微服务架构可以一个服务对应一个数据库,同一个信息被存储到不同数据库
public Dept(String dname) {
super();
this.dname = dname;
}
/*public static void main(String[] args) {
Dept dept = new Dept();
dept.setDeptno(11L).setDname("RD").setDb_source("DB01");
}*/
}
03. microservicecloud-provider-dept-8001 (微服务提供者)
4.0.0
com.atguigu.springcloud
microservicecloud
0.0.1-SNAPSHOT
microservicecloud-provider-dept-8001
com.atguigu.springcloud
microservicecloud-api
${project.version}
org.springframework.boot
spring-boot-starter-actuator
org.springframework.cloud
spring-cloud-starter-eureka
org.springframework.cloud
spring-cloud-starter-config
junit
junit
mysql
mysql-connector-java
com.alibaba
druid
ch.qos.logback
logback-core
org.mybatis.spring.boot
mybatis-spring-boot-starter
org.springframework.boot
spring-boot-starter-jetty
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
org.springframework
springloaded
org.springframework.boot
spring-boot-devtools
03-1.application.yml 文件放进 resources目录下
server:
port: 8001
mybatis:
config-location: classpath:mybatis/mybatis.cfg.xml # mybatis配置文件所在路径
type-aliases-package: com.atguigu.springcloud.entities # 所有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: 123456
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$
03-2 .Java代码
package com.atguigu.springcloud.controller;
import java.util.List;
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.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.atguigu.springcloud.entities.Dept;
import com.atguigu.springcloud.service.DeptService;
/**
* 服务提供端
*
* @Filename: DeptController.java
* @Version: 1.0
* @Author: 余健
* @Email: [email protected]
*
*/
@RestController
public class DeptController {
@Autowired
private DeptService service;
@Autowired
private DiscoveryClient client;
@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 list() {
return service.list();
}
// @Autowired
// private DiscoveryClient client;
@RequestMapping(value = "/dept/discovery", method = RequestMethod.GET)
public Object discovery() {
List list = client.getServices();
System.out.println("**********" + list);
List srvList = client.getInstances("MICROSERVICECLOUD-DEPT");
for (ServiceInstance element : srvList) {
System.out.println(element.getServiceId() + "\t" + element.getHost() + "\t" + element.getPort() + "\t"
+ element.getUri());
}
return this.client;
}
}
package com.atguigu.springcloud.dao;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import com.atguigu.springcloud.entities.Dept;
@Mapper
public interface DeptDao {
public boolean addDept(Dept dept);
public Dept findById(Long id);
public List findAll();
}
package com.atguigu.springcloud.service;
import java.util.List;
import com.atguigu.springcloud.entities.Dept;
public interface DeptService {
public boolean add(Dept dept);
public Dept get(Long id);
public List list();
}
package com.atguigu.springcloud.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.atguigu.springcloud.dao.DeptDao;
import com.atguigu.springcloud.entities.Dept;
import com.atguigu.springcloud.service.DeptService;
@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 list() {
return dao.findAll();
}
}
man方法直接放在com.atguigu.springcloud目录下
package com.atguigu.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient //本服务启动后会自动注册进eureka服务中
//@EnableDiscoveryClient //服务发现
public class DeptProvider8001_App {
public static void main(String[] args) {
SpringApplication.run(DeptProvider8001_App.class, args);
}
}
04.microservicecloud-consumer-dept-80(微服务消费者)
4.0.0
com.atguigu.springcloud
microservicecloud
0.0.1-SNAPSHOT
microservicecloud-consumer-dept-80
部门微服务消费者
com.atguigu.springcloud
microservicecloud-api
${project.version}
org.springframework.cloud
spring-cloud-starter-eureka
org.springframework.cloud
spring-cloud-starter-ribbon
org.springframework.cloud
spring-cloud-starter-config
org.springframework.boot
spring-boot-starter-web
org.springframework
springloaded
org.springframework.boot
spring-boot-devtools
package com.atguigu.myrule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RoundRobinRule;
@Configuration
public class MySelfRule
{
@Bean
public IRule myRule()
{
//return new RandomRule();// Ribbon默认是轮询,我自定义为随机
//return new RoundRobinRule();// Ribbon默认是轮询,我自定义为随机
return new RandomRule_ZY();// 我自定义为每台机器5次
}
}
package com.atguigu.myrule;
import java.util.List;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
public class RandomRule_ZY extends AbstractLoadBalancerRule
{
// total = 0 // 当total==5以后,我们指针才能往下走,
// index = 0 // 当前对外提供服务的服务器地址,
// total需要重新置为零,但是已经达到过一个5次,我们的index = 1
// 分析:我们5次,但是微服务只有8001 8002 8003 三台,OK?
//
private int total = 0; // 总共被调用的次数,目前要求每台被调用5次
private int currentIndex = 0; // 当前提供服务的机器号
public Server choose(ILoadBalancer lb, Object key)
{
if (lb == null) {
return null;
}
Server server = null;
while (server == null) {
if (Thread.interrupted()) {
return null;
}
List upList = lb.getReachableServers();
List allList = lb.getAllServers();
int serverCount = allList.size();
if (serverCount == 0) {
/*
* No servers. End regardless of pass, because subsequent passes only get more
* restrictive.
*/
return null;
}
// int index = rand.nextInt(serverCount);// java.util.Random().nextInt(3);
// server = upList.get(index);
// private int total = 0; // 总共被调用的次数,目前要求每台被调用5次
// private int currentIndex = 0; // 当前提供服务的机器号
if(total < 5)
{
server = upList.get(currentIndex);
total++;
}else {
total = 0;
currentIndex++;
if(currentIndex >= upList.size())
{
currentIndex = 0;
}
}
if (server == null) {
/*
* The only time this should happen is if the server list were somehow trimmed.
* This is a transient condition. Retry after yielding.
*/
Thread.yield();
continue;
}
if (server.isAlive()) {
return (server);
}
// Shouldn't actually happen.. but must be transient or a bug.
server = null;
Thread.yield();
}
return server;
}
@Override
public Server choose(Object key)
{
return choose(getLoadBalancer(), key);
}
@Override
public void initWithNiwsConfig(IClientConfig clientConfig)
{
// TODO Auto-generated method stub
}
}
package com.atguigu.springcloud.cfgbeans;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class ConfigBean // boot -->spring applicationContext.xml --- @Configuration配置 ConfigBean =
// applicationContext.xml
{
@Bean
// @LoadBalanced // Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端 负载均衡的工具。
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
/*
* @Bean public IRule myRule() { // return new RoundRobinRule(); // return new
* RandomRule();//达到的目的,用我们重新选择的随机算法替代默认的轮询。 return new RetryRule(); }
*/
}
//@Bean
//public UserServcie getUserServcie()
//{
// return new UserServcieImpl();
//}
// applicationContext.xml == ConfigBean(@Configuration)
//
package com.atguigu.springcloud.controller;
import java.util.List;
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 com.atguigu.springcloud.entities.Dept;
/**
* 服务消费端
*
* @Filename: DeptController_Consumer.java
* @Version: 1.0
* @Author: 余健
* @Email: [email protected]
*
*/
@RestController
public class DeptController_Consumer {
private static final String REST_URL_PREFIX = "http://localhost:8001";
// private static final String REST_URL_PREFIX = "http://MICROSERVICECLOUD-DEPT";
/**
* 使用 使用restTemplate访问restful接口非常的简单粗暴无脑。 (url, requestMap,
* ResponseBean.class)这三个参数分别代表 REST请求地址、请求参数、HTTP响应转换被转换成的对象类型。
*/
@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 list() {
return restTemplate.getForObject(REST_URL_PREFIX + "/dept/list", List.class);
}
// 测试@EnableDiscoveryClient,消费端可以调用服务发现
@RequestMapping(value = "/consumer/dept/discovery")
public Object discovery() {
return restTemplate.getForObject(REST_URL_PREFIX + "/dept/discovery", Object.class);
}
}
package com.atguigu.springcloud;
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;
import com.atguigu.myrule.MySelfRule;
@SpringBootApplication
//@EnableEurekaClient
//在启动该微服务的时候就能去加载我们的自定义Ribbon配置类,从而使配置生效
//@RibbonClient(name="MICROSERVICECLOUD-DEPT",configuration=MySelfRule.class)
//@RibbonClient(name="MICROSERVICECLOUD-DEPT",configuration=MySelfRule.class)
public class DeptConsumer80_App
{
public static void main(String[] args)
{
SpringApplication.run(DeptConsumer80_App.class, args);
}
}
04-1.application.yml 文件放进 resources目录下
server:
port: 80
#eureka:
# client:
# register-with-eureka: false
# service-url:
# defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
05.microservicecloud-eureka-7001(eureka服务注册中心)
4.0.0
com.atguigu.springcloud
microservicecloud
0.0.1-SNAPSHOT
microservicecloud-eureka-7001
org.springframework.cloud
spring-cloud-starter-eureka-server
org.springframework
springloaded
org.springframework.boot
spring-boot-devtools
org.springframework.boot
spring-boot-starter-security
eureka-7001
org.springframework.boot
spring-boot-maven-plugin
1.4.2.RELEASE
repackage
Java代码
package com.atguigu.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication //springBoot启动类必需注解
@EnableEurekaServer // EurekaServer服务器端启动类,接受其它微服务注册进来
public class EurekaServer7001_App
{
public static void main(String[] args)
{
SpringApplication.run(EurekaServer7001_App.class, args);
}
}
05-1.application.yml 文件放进 resources目录下
server:
port: 7001
eureka:
instance:
hostname: eureka7001.com #eureka服务端的实例名称
client:
register-with-eureka: false #false表示不向注册中心注册自己。
fetch-registry: false #false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
service-url:
#单机
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ #设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址(单机)。
#集群
#defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
数据库表(数据什么的就自己随便塞点进去吧)
CREATE TABLE `dept` (
`deptno` int(16) NOT NULL AUTO_INCREMENT,
`dname` varchar(32) DEFAULT NULL,
`db_source` varchar(32) DEFAULT NULL,
PRIMARY KEY (`deptno`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8