Eureka Server入门项目搭建
(刚开始学习微服务架构,来记录下.)
一:单体应用与微服务
1.单体应用缺点
1.1 开发速度慢
1. 2 启动时间长
1. 3 依赖庞大
......等等
2.什么是微服务
2.1. 微服务架构设计代表了一种架构设计思想,再配合上容器技术(如Docker),可以在程序开发上的流程、 部署、服务维护等各方面的效率得到很大提升。
2.2. 微服务就是将一个单体架构的应用按业务划分为一个个的独立运行的程序即服务,它们之间通过 HTTP协议进行通信(也可以采用消息队列来通信,如 RoocketMQ,Kafaka等),可以采用不同的编程语言,使用不同的存储技术,自动化部署(如Jenkins)减少人为控制,降低出错概率。服务数量越多,管理起来越复杂,因此采用集中化管理。例如 Eureka,Zookeeper等都是比较常见的服务集中化管理框架
2.3. .........
3.微服务的好处
3.1. 可以将一个庞大的单体架构的应用按业务切分为多个具有不同服务的程序应用,各自独立运行,每个服务都有一个定义清楚的边界,通过 RPC- 或者消息驱动API与外接沟通,单个微服务相比单体应用更容易开发和维护.
3.2. 微服务架构使得每个微服务独立部署。加快部署速度,这样一来,每个服务都属于一个单独的个体,对服务的维护,升级,扩展等带来极大的便利
3.3. .....
4.微服务架构的不足之处
4.1. 微服务应用是一个分布式系统,由此会带来分布式系统固有的复杂性.
4.2. 多个服务之间的依赖问题,相关应用的升级以及修改等有可能会波及多个服务模块的修改.在以往单体应用中,只需要修改相关的模块便可,整合后一并部署。而微服务架构模式,修改服务模块时就需要考虑服务间的依赖关系
4.3. 分布式系统--->分布式事务问题
4.4. 需要管理多个服务-->服务治理
另:微服务核心知识 :网关、服务发现注册、配置中心、链路追踪、负载均衡器、熔断...等
1. 网关:路由转发 + 过滤器
/api/v1/pruduct/ 商品服务
/api/v1/order/ 订单服务
/api/v1/user/ 用户服务
2. 服务注册发现:调用和被调用方的信息维护
3. 配置中心:管理配置,动态更新 application.properties
4. 链路追踪:分析调用链路耗时
例子:下单-》查询商品服务获取商品价格-》查询用户信息-》保存数据库
5. 负载均衡器:分发负载
6. 熔断:保护自己和被调用方
常见的微服务框架:
1. consumer: 调用方
2. provider: 被调用方
一个接口一般都会充当两个角色(不是同时充当)
1、dubbo: zookeeper + dubbo + springmvc/springboot
官方地址:http://dubbo.apache.org/#!/?lang=zh-cn
配套
通信方式:rpc
注册中心:zookeper/redis
配置中心:diamond
2、springcloud: 全家桶+轻松嵌入第三方组件(Netflix 奈飞)
官网:http://projects.spring.io/spring-cloud/
配套
通信方式:http restful
注册中心:eruka/consul
配置中心:config
断路器:hystrix
网关:zuul
分布式追踪系统:sleuth+zipkin
二:搭建步骤
(刚开始学习,我这里使用的是Eureka)
**项目结构:**
(我这里按照习惯,建的是"父子工程",当然也可以新建两个独立工程,编辑器:IDEA)
1.新建一个空白的父工程,src以及其他暂时用不着的东西可以先删除
(步骤略)
2.新建第一个Module,用来做"注册中心"
入门项目,业务不多,依赖选择一个即可,项目创建好后的依赖:
1.8
Hoxton.RELEASE
org.springframework.cloud
spring-cloud-starter-netflix-eureka-server
org.springframework.boot
spring-boot-starter-test
test
org.junit.vintage
junit-vintage-engine
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
3.在启动类上添加注解:@EnableEurekaServer
4.添加配置(application.yml):
server:
port: 8761
eureka:
instance:
hostname: localhost
client:
#声明自己是服务端
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
5.启动服务:方式跟平常启动sprinboot应用一样
浏览器输入:http://localhost:8761/
一个简单的"注册中心"创建完毕
6.创建第二个Module:商品服务
依赖选择:
7.分别创建实体类,service,controller;
实体类:
//Product.java
package com.xt.tools.eureka.product_server.domain;
import lombok.Data;
/*
* @description: 说明
* @author: 小谭
* @date: 2019/12/5 20:04
*/
@Data
public class Product {
private int id;
private String name;
private int price;
private int store;
public Product(int id, String name, int price, int store) {
this.id = id;
this.name = name;
this.price = price;
this.store = store;
}
public Product() {}
}
service接口:
//ProductService.java
package com.xt.tools.eureka.product_server.service;
import com.xt.tools.eureka.product_server.domain.Product;
import java.util.List;
/*
* @description: 说明
* @author: 小谭
* @date: 2019/12/5 20:06
*/
public interface ProductService {
List
ListProduct(); Product findById(int id);
}
service接口实现类:
package com.xt.tools.eureka.product_server.service;
import com.xt.tools.eureka.product_server.domain.Product;
import org.springframework.stereotype.Service;
import java.util.*;
/*
* @description: 说明
* @author: 小谭
* @date: 2019/12/5 20:09
*/
@Service
public class ProductServiceImpl implements ProductService {
private static Map
daoMap = new HashMap<>(); static {
Product p1 = new Product(1,"iphonex",9999, 10);
Product p2 = new Product(2,"冰箱",5342, 19);
Product p3 = new Product(3,"洗衣机",523, 90);
Product p4 = new Product(4,"电话",64345, 150);
Product p5 = new Product(5,"汽车",2345, 140);
Product p6 = new Product(6,"椅子",253, 20);
Product p7 = new Product(7,"java编程思想",2341, 10);
daoMap.put(p1.getId(),p1);
daoMap.put(p2.getId(),p2);
daoMap.put(p3.getId(),p3);
daoMap.put(p4.getId(),p4);
daoMap.put(p5.getId(),p5);
daoMap.put(p6.getId(),p6);
daoMap.put(p7.getId(),p7);
}
@Override
public List
ListProduct() { Collection
values = daoMap.values(); List
products = new ArrayList<>(values); return products;
}
@Override
public Product findById(int id) {
return daoMap.get(id);
}
}
controller:
package com.xt.tools.eureka.product_server.controller;
import com.xt.tools.eureka.product_server.service.ProductService;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/*
* @description: 说明
* @author: 小谭
* @date: 2019/12/5 20:03
*/
@RestController
@RequestMapping("/api/v1/product")
public class productController {
@Autowired
private ProductService productService;
@RequestMapping("list")
public Object List(){
return productService.ListProduct();
}
@RequestMapping("find")
public Object product(@RequestParam("id") int id){
return productService.findById(id);
}
}
最后,配置文件:
server:
port: 8771
#指定spring应用名称
spring:
application:
name: product-server
#指定注册中心地址
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
现在可以启动服务了,至于这个Module的启动类的注解:@EnableEurekaClient,可加可不加
(1):http://localhost:8771/api/v1/product/list
(2):http://localhost:8771/api/v1/product/find?id=2
有数据返回,功能一切正常,再来刷新一下注册中心:
与开始相比,页面多出了一些东西,目前,商品服务已成功注册进去了,
问题一:eureka管理后台出现一串红色字体:是警告,说明有服务上线率低
EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.
关闭检查方法:eureka服务端配置文件加入
server:
enable-self-preservation: false
注意:自我保护模式禁止关闭,默认是开启状态true
问题二:为什么只加一个注册中心地址,就可以注册
官方解释:(https://cloud.spring.io/spring-cloud-netflix/reference/html/#service-discovery-eureka-clients):
By having spring-cloud-starter-netflix-eureka-client on the classpath, your application automatically registers with the Eureka Server. Configuration is required to locate the Eureka server, as shown in the following example:
google翻译:
通过在类路径上使用spring-cloud-starter-netflix-eureka-client,您的应用程序将自动向Eureka Server注册。需要配置以找到Eureka服务器,如以下示例所示
github项目: https://github.com/XT962464oo/Eureka_demo