SOA思想
面向服务的架构(SOA)是一个组件模型,它将应用程序的不同功能单元(称为服务)进行拆分,并通过这些服务之间定义良好的接口和协议联系起来。接口是采用中立的方式进行定义的,它应该独立于实现服务的硬件平台、操作系统和编程语言。这使得构件在各种各样的系统中的服务可以以一种统一和通用的方式进行交互。
RPC(统称/思想)
RPC介绍
RPC是远程过程调用(Remote Procedure Call)的缩写形式。由不同的服务之间进行的通讯就称之为RPC,RPC通讯用户无需了解协议的细节.像调用本地服务一样简单. RPC调用本质就是代理思想的应用.
注册中心
说明:
1.使用传统的架构设计,所有的请求都经过NGINX负责中转,则nginx负载很大,如果nginx出现了问题,则直接影响用户.
2.如果服务器的数量改变了,则必然要修改nginx的配置文件.
需求: 1.保证nginx负载压力不要太高.
2.如果服务器数量发生变化,则可以自动的更新配置.,无需人为的干预
注册中心原理说明
原理说明:
1).当服务器启动时,提供者/生产者会将自己的服务名称/IP:PORT写入注册中心.
2).当注册中心接收提供者数据时,会动态的维护服务列表数据.
3).当消费者服务器启动时,会链接注册中心.获取服务列表数据.
4).当请求注册中心之后,则将服务列表保存到本地(消费者内存中),方便以后使用.
5).根据已知的服务提供者 利用负载均衡(有框架操作 不由注册中心操作)机制挑选其中一个进行访问.
6).当注册中心利用心跳检查机制发现服务提供者宕机时,会"同步更新"注册列表,并且"同步所有消费者的服务列表".
注册中心的集群搭建(dubbo框架的注册中心 zookeeper)
公式: 剩余的主节点 > N/2
分析:
1个节点能否搭建集群? 1-1 > 0.5 假 不能搭建集群
2个节点能否搭建集群? 2-1 > 1 假 不能搭建集群
3个节点能否搭建集群? 3-1 > 1.5 真 可以搭建集群
4个节点能否搭建集群> 4-1 > 2 真 可以搭建集群
分析集群宕机的条件:
3个节点最多允许宕机1台. 奇数
4个节点最多允许宕机1台 偶数
奇数台和偶数台容灾能力相同.所以为了节省资源,一般集群都是奇数台.
结论:1).搭建集群最小单位 3台.
2).一般集群搭建都是奇数台.
zookeeper单台 安装
Zookeeper负责服务的协调调度.当客户端发起请求时,返回正确的服务器地址.
下载地址
链接: https://zookeeper.apache.org/releases.html.
安装 (必须安装了JDK)
- 解压
tar -xvf zookeeper-3.4.8.tar.gz
2.在 zk(zookeeper)根目录下创建文件夹 data / log
mkdir data log
3.跳入conf目录中修改配置文件
复制配置文件并且修改名称
cp zoo_sample.cfg zoo.cfg
4. 跳转到bin目录下 启动或者关闭 zk
sh zkServer.sh start或者./zkServer.sh start
sh zkServer.sh stop
sh zkServer.sh status
zookeeper 集群搭建
- 准备文件夹 在zookeeper根目录中创建新的文件夹zkCluster.
- 在zkCluster中 创建 zk1 zk2 zk3
3.在每个文件夹中创建 data/log 文件
mkdir {zk1,zk2,zk3}/{data,log}
3. 添加myid文件
分别在zk1/zk2/zk3中的data文件夹中创建新的文件myid.其中的内容依次为1/2/3,与zk节点号对应.
4.编辑myid文件,定义编号 其中的内容依次为1/2/3,与zk节点号对应.
。。。
-
编辑配置文件 进入conf目录 将zoo_sample.cfg复制为zoo1.cfg之后修改配置文件.
-
修改 zoo1.cfg
配置完成后将zoo1.cfg复制2份.之后需要修改对应的文件夹目录.和不同的端口即可. -
集群测试 进入 bin 目录
sh zkServer.sh start zoo1.cfg
sh zkServer.sh stopzoo1.cfg
Zookeeper集群中leader负责监控集群状态,follower主要负责客户端链接获取服务列表信息.同时参与投票.
dubbo 框架
1.介绍
Apache Dubbo |ˈdʌbəʊ| 是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现
链接: http://dubbo.apache.org/en-us/.
依赖
<!--提供者需要实现第三方接口,则必须依赖第三方项目-->
<dependencies>
<dependency>
<groupId>com.jt.dubbo</groupId>
<artifactId>dubbo-jt-demo-interface</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
入门案例
建立pom 工程 创建 公共接口
2. 定义pojo 实体对象
package com.jt.dubbo.pojo;
import java.io.Serializable;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.experimental.Accessors;
@Data
@Accessors(chain=true)
@TableName //如果对象名称与表名一致,则可以省略不写.
public class User implements Serializable{ //必须实例化 用于服务间的信息传输
//dubbo协议中传输的对象必须序列化
private static final long serialVersionUID = 1L;
@TableId(type=IdType.AUTO)
private Integer id;
private String name;
private Integer age;
private String sex;
}
定义 公共接口
package com.jt.dubbo.service;
import java.util.List;
import org.springframework.transaction.annotation.Transactional;
import com.jt.dubbo.pojo.User;
public interface UserService {
//查询全部的用户信息
List<User> findAll();
//新增用户入库操作.
@Transactional
void saveUser(User user);
}
创建服务提供者
- 添加公共接口的依赖项
<!--提供者需要实现第三方接口,则必须依赖第三方项目-->
<dependencies>
<dependency>
<groupId>com.jt.dubbo</groupId>
<artifactId>dubbo-jt-demo-interface</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
2.编辑提供者的实现类
package com.jt.dubbo.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import com.alibaba.dubbo.config.annotation.Service;
import com.jt.dubbo.mapper.UserMapper;
import com.jt.dubbo.pojo.User;
@Service(timeout=3000) //3秒超时 使用dubbo的注解
//注意 是dubbo注解中的service
public class UserServiceImpl implements UserService { //实现公共的第三方接口
@Autowired
private UserMapper userMapper;
/*
userService接口只是定义规范.不负责具体的实现.将来由服务的提供者实现该功能.
* */
@Override
public List<User> findAll() {
System.out.println("我是第一个服务的提供者");
return userMapper.selectList(null);
}
@Override
public void saveUser(User user) {
userMapper.insert(user);
}
}
4.编辑 配置文件
server:
port: 9000 #定义端口
spring:
datasource:
#引入druid数据源
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/jtdb?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
username: root
password: root
#关于Dubbo配置
dubbo:
scan:
basePackages: com.jt #指定dubbo的包路径 扫描dubbo的注解
application: #应用名称
name: provider-user #相同的接口 服务名称必定一致. 不同的接口服务名称一定不一致.
registry: #配置注册中心
address: zookeeper://192.168.126.129:2181?backup=192.168.126.129:2182,192.168.126.129:2183
protocol: #指定协议
name: dubbo #使用dubbo协议(tcp-ip) web-controller直接调用sso-Service
port: 20880 #每一个服务都有自己特定的端口 不能重复.
mybatis-plus:
type-aliases-package: com.jt.dubbo.pojo #配置别名包路径
mapper-locations: classpath:/mybatis/mappers/*.xml #添加mapper映射文件
configuration:
map-underscore-to-camel-case: true #开启驼峰映射规则
配置消费者
- 添加公共接口依赖项
<dependencies>
<dependency>
<groupId>com.jt.dubbo</groupId>
<artifactId>dubbo-jt-demo-interface</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
编辑消费者 controller
由于消费者 不需要连接数据库 又因为是聚合工程 所以已经导入了jdbc。。。 所以在启动类上添加注解
package com.jt;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
@SpringBootApplication(exclude=DataSourceAutoConfiguration.class)
public class SpringBoot_Run {
public static void main(String[] args) {
SpringApplication.run(SpringBoot_Run.class, args);
}
}
package com.jt.dubbo.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.alibaba.dubbo.config.annotation.Reference;
import com.jt.dubbo.pojo.User;
import com.jt.dubbo.service.UserService;
@RestController
public class UserController {
//定义第三方接口 利用代理机制为其创建代理对象 用起来和本地服务一样.实质调用的是远程服务.
@Reference(check=false,loadbalance="leastactive")//loadbalance="leastactive" 负载均衡
//@Autowired
private UserService userService;
/**
* Dubbo框架调用特点:远程RPC调用就像调用自己本地服务一样简单
* @return
*/
@RequestMapping("/findAll")
public List<User> findAll(){
//远程调用时传递的对象数据必须序列化.
return userService.findAll();
}
@RequestMapping("/saveUser/{name}/{age}/{sex}")
public String saveUser(User user) {
userService.saveUser(user);
return "用户入库成功!!!";
}
}
配置yml文件
server:
port: 9001
dubbo:
scan:
basePackages: com.jt
application:
name: consumer-user #定义消费者名称
registry: #注册中心地址
address: zookeeper://192.168.126.129:2181?backup=192.168.126.129:2182,192.168.126.129:2183
loadbalance 负载均衡 默认随机算法
hash一致性算法 说明:消费者访问绑定了指定的提供者
//要求所有的字母全部小写
@Reference(loadbalance="consistenthash")
private UserService userService;
最小访问量 挑选当前服务器访问压力最小的服务器进行访问
//要求所有的字母全部小写
@Reference(loadbalance="leastactive")
private UserService userService;
随机算法 该算法是默认的配置
//要求所有的字母全部小写
@Reference(loadbalance="random")
private UserService userService;
轮询算法 根据配置依次轮询访问
//要求所有的字母全部小写
@Reference(loadbalance="roundrobin")
private UserService userService;