一、微服务
1、微服务的特点
- 单一职责:微服务中每一个服务都对应唯一的业务能力,做到单一职责
- 微:微服务的服务拆分粒度很小,例如一个用户管理就可以作为一个服务。每个服务虽小,但“五脏俱全”。
- 面向服务:面向服务是说每个服务都要对外暴露Rest风格服务接口API。并不关心服务的技术实现,做到与平台和语言无关,也不限定用什么技术实现,只要提供Rest的接口即可。
- 自治:自治是说服务间互相独立,互不干扰
- 团队独立:每个服务都是一个独立的开发团队,人数不能过多。
- 技术独立:因为是面向服务,提供Rest接口,使用什么技术没有别人干涉
- 前后端分离:采用前后端分离开发,提供统一Rest接口,后端不用再为PC、移动段开发不同接口
- 数据库分离:每个服务都可以使用自己的数据源
- 部署独立,服务间虽然有调用,但要做到服务重启不影响其它服务。有利于持续集成和持续交付。每个服务都是独立的组件,可复用,可替换,降低耦合,易维护
2.服务的调用方式
- RPC:Remote Produce Call远程过程调用,类似的还有RMI。自定义数据格式,基于原生TCP通信,速度快,效率高。早期的webservice,现在热门的dubbo,都是RPC的典型代表
- Http:http其实是一种网络传输协议,基于TCP,规定了数据传输的格式。现在客户端浏览器与服务端通信基本都是采用Http协议,也可以用来进行远程服务调用。缺点是消息封装臃肿,优势是对服务的提供和调用方没有任何技术限定,自由灵活,更符合微服务理念。
- 如果你们公司全部采用Java技术栈,那么使用Dubbo作为微服务架构是一个不错的选择。
- 如果公司的技术栈多样化,而且你更青睐Spring家族,那么SpringCloud搭建微服务是不二之选。在我们的项目中,我们会选择SpringCloud套件,因此我们会使用Http方式来实现服务间调用。
3.Http客户端工具(了解)
-
HttpClient
-
OKHttp
-
URLConnection
4、项目eureka使用
1、创建工程
添加dependencies:
eureka : eureka server
provider : eureka discovery client 、spring web
Consumer : eureka discovery client 、spring web
2、eureka注册中心
application.properties配置文件
server.port=5555
# 应用名称
spring.application.name=eureka-server
# false表示不向注册中心注册自己
eureka.client.register-with-eureka=false
# false表示取消服务检索,Eureka Server用于维护服务实例,不需要检索服务
eureka.client.fetch-registry=false
#设置Eureka注册中心访问地址,端口后面必须为/eureka,单词不能写错;
eureka.client.serviceUrl.defaultZone=http://127.0.0.1:5555/eureka
EurekaApplication启动类
//启动类上添加@EnableEurekaServer 启动注册中心
@EnableEurekaServer
@SpringBootApplication
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class, args);
}
}
3、provider生产者
vo层:
package com.jd.vo;
import java.io.Serializable;
public class Address implements Serializable {
private static final long serialVersionUID = 5305546635635321215L;
private String id;//主键
private String userId; //用户id
private String name;//姓名
private String mobile;//手机号
private String detail; //详细信息
public Address(String id, String userId, String name, String mobile, String detail) {
this.id = id;
this.userId = userId;
this.name = name;
this.mobile = mobile;
this.detail = detail;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getDetail() {
return detail;
}
public void setDetail(String detail) {
this.detail = detail;
}
}
application.properties配置文件
# 应用名称
spring.application.name=provider
# 应用服务 WEB 访问端口
server.port=7777
#指定Eureka注册中心访问地址
eureka.client.serviceUrl.defaultZone=http://127.0.0.1:5555/eureka
#是否从Eureka注册中心抓取已有的注册消息,默认为true,单节点无所谓true或false,但是集群必须设置为true才能配合ribbon使用负载均衡
#eureka.client.fetch-registry=true
service层
IAddressService:接口
package com.jd.service;
public interface IAddressService {
List<Address> getByUserId(String userId);
}
AddressService:实现
package com.jd.service;
@Service
public class AddressService implements IAddressService {
public List<Address> getByUserId(String userId) {
System.out.println("AddressService.......20880");
List<Address> list = new ArrayList<Address>();
if("9099ebc5-10bc-4b4a-94ac-4a77e42cd47c".equals(userId)) {
list.add(new Address("6bf28ab4-3ebd-4548-bd11-b9b3ae40dcbf", "9099ebc5-10bc-4b4a-94ac-4a77e42cd47c", "汤丞昱", "19966254888", "河南郑州市高新技术开发区朗月公园茂"));
list.add(new Address("43c0d340-838c-464a-98d4-35966374696d", "9099ebc5-10bc-4b4a-94ac-4a77e42cd47c", "钱勤堃", "17638588870", "新疆自治区乌鲁木齐市头屯河区乌西五街小区"));
list.add(new Address("7581325c-0a04-4015-9873-f055fae47804", "9099ebc5-10bc-4b4a-94ac-4a77e42cd47c", "李明", "15313933139", "北京北京市海淀区万寿路街道万寿园小区"));
}
return list;
}
}
controller层:
package com.jd;
@Controller
public class AddressController {
@Autowired
private IAddressService addressService;
@ResponseBody
@GetMapping("/address/list.do")
public List<Address> list(String userId) {
return addressService.getByUserId(userId);
}
}
ProviderApplication:启动类
package com.jd;
//启动类上添加@EnableEurekaClient
@EnableEurekaClient
@SpringBootApplication
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
}
4、consumer消费者
application.properties配置文件
# 应用名称
spring.application.name=order-consumer
# 应用服务 WEB 访问端口
server.port=9999
#指定Eureka注册中心访问地址
eureka.client.serviceUrl.defaultZone=http://127.0.0.1:5555/eureka
config配置层:
ApplicationConfiguration
package com.jd.configration;
@Configuration
public class ApplicationConfiguration {
@Bean
public RestTemplate template(){
return new RestTemplate();
}
}
OrderController层
package com.jd;
@Controller
public class OrderController {
@Autowired
private RestTemplate template;
@ResponseBody
@RequestMapping("/order/info.do")
public Map<String,Object> info(String userId) {
Map<String,Object> map = new HashMap<>();
map.put("addressList",template.getForObject("http://127.0.0.1:7777/address/list.do?userId="+userId,Object.class));
map.put("goodsList",null);
return map;
}
}
ConsumerApplication启动类
package com.jd;
//同样添加@EnableEurekaClient
@EnableEurekaClient
@SpringBootApplication
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
}
5、eureka配置文件配置解释(了解)
- eureka.client.register-with-eureka 是否注册到eureka服务中,false表示不向注册中心注册自己
- fetch-registry 是否拉取其他的服务,false表示取消服务检索,Eureka Server用于维护服务实例,不需要检索服务
- lease-renewal-interval-in-seconds:服务续约(renew)的间隔,默认为30秒
- lease-expiration-duration-in-seconds:服务失效时间,默认值90秒
- enable-self-preservation false # 关闭自我保护模式(缺省为打开)
- eviction-interval-timer-in-ms: 1000 # 扫描失效服务的间隔时间(缺省为60*1000ms)