Dubbo
一、Dubbo是什么? Dubbo是阿里巴巴开源的基于 Java 的高性能 RPC(一种远程调用) 分布式服务框架(SOA),致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。 二、为什么要用Dubbo? 因为是阿里开源项目,国内很多互联网公司都在用,已经经过很多线上考验。内部使用了 Netty、Zookeeper,保证了高性能高可用性。
|
1 2 3 |
1、使用Dubbo可以将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,可用于提高业务复用 灵活扩展,使前端应用能更快速的响应多变的市场需求。 2、分布式架构可以承受更大规模的并发流量。 |
三、Dubbo 和 Spring Cloud 有什么区别?
|
1 2 3 4 5 |
1、通信方式不同:Dubbo 使用的是 RPC 通信,而Spring Cloud 使用的是HTTP RESTFul 方式。 2、组成不一样: dubbo的服务注册中心为Zookeerper,服务监控中心为dubbo-monitor,无消息总线,服务跟踪、批量任务等组件; spring-cloud的服务注册中心为spring-cloud netflix enruka,服务监控中心为spring-boot admin,有消息总线,数据流、服务跟踪、批量任务等组件; 四、Dubbo需要 Web 容器吗? |
不需要,如果硬要用Web 容器,只会增加复杂性,也浪费资源。 五、Dubbo内置了哪几种服务容器?
|
1 2 3 4 |
三种服务容器: 1、Spring Container 2、Jetty Container 3、Log4j Container |
Dubbo 的服务容器只是一个简单的 Main 方法,并加载一个简单的 Spring 容器,用于暴露服务。 六、dubbo都支持什么协议,推荐用哪种?
|
1 2 3 4 5 |
1、dubbo://(推荐) 2、http:// 3、rest:// 4、redis:// 5、memcached:// |
七、Dubbo里面有哪几种节点角色?
|
1 2 3 4 5 |
1、provide:暴露服务的服务提供方 2、consumer:调用远程服务的服务消费方 3、registry:服务注册于发现的注册中心 4、monitor:统计服务调用次数和调用时间的监控中心 5、container:服务运行容器 |
八、dubbo服务注册与发现的流程图 dubbo服务注册与发现的流程图 九、Dubbo默认使用什么注册中心,还有别的选择吗? 推荐使用zookeeper作为注册中心,还有redis、multicast、simple注册中心。 十、Dubbo 核心的配置有哪些? Dubbo 核心的配置 十一、在 Provider 上可以配置的 Consumer 端的属性有哪些?
|
1 2 3 4 |
1、timeout:方法调用超时 2、retries:失败重试次数,默认重试 2 次 3、loadbalance:负载均衡算法,默认随机 4、actives 消费者端,最大并发调用限制 |
十二、Dubbo有哪几种负载均衡策略,默认是哪种?
|
1 2 3 4 |
1、random loadbalance:安权重设置随机概率(默认); 2、roundrobin loadbalance:轮寻,按照公约后权重设置轮训比例; 3、lastactive loadbalance:最少活跃调用数,若相同则随机; 4、consistenthash loadbalance:一致性hash,相同参数的请求总是发送到同一提供者。 |
十三、Dubbo启动时如果依赖的服务不可用会怎样? Dubbo缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止 Spring 初始化完成,默认 check="true",可以通过 check="false" 关闭检查。 十四、Dubbo推荐使用什么序列化框架,你知道的还有哪些?
|
1 |
推荐使用Hessian序列化,还有Duddo、FastJson、Java自带序列化; |
十五、Dubbo默认使用的是什么通信框架,还有别的选择吗?
|
1 |
Dubbo 默认使用 Netty 框架,也是推荐的选择,另外内容还集成有Mina、Grizzly。 |
十六、Dubbo有哪几种集群容错方案,默认是哪种? Dubbo集群容错方案 十七、服务提供者能实现失效踢出是什么原理?
|
1 |
服务失效踢出基于zookeeper的临时节点原理。 |
十八、Dubbo服务之间的调用是阻塞的吗?
|
1 2 3 |
默认是同步等待结果阻塞的,支持异步调用。 Dubbo 是基于 NIO 的非阻塞实现并行调用,客户端不需要启动多线程即可完成并行调用多个远程服务,相对 多线程开销较小,异步调用会返回一个 Future 对象。 |
Dubbo暂时不支持分布式事务。 十九、Dubbo的管理控制台能做什么?
|
1 2 |
管理控制台主要包含:路由规则,动态配置,服务降级,访问控制,权重调整,负载均衡,等管理功能。 注:dubbo源码中的dubbo-admin模块打成war包,发布运行即可得到dubbo控制管理界面。 |
二十、Dubbo 服务暴露的过程
|
1 2 3 4 |
Dubbo 会在 Spring 实例化完 bean 之后,在刷新容器最后一步发布 ContextRefreshEvent 事件的时候,通知 实现了 ApplicationListener 的 ServiceBean 类进行回调 onApplicationEvent 事件方法,Dubbo 会在这个方法 中调用 ServiceBean 父类 ServiceConfig 的 export 方法,而该方法真正实现了服务的(异步或者非异步)发 布。 |
二十一、当一个服务接口有多种实现时怎么做? 当一个接口有多种实现时,可以用 group 属性来分组,服务提供方和消费方都指定同一个 group […]
View Details人生42准则 – 乔丹彼得森
1.说真话。 2.不要做你讨厌的事情。 3.让你的行为与想法保持一致。 4.追求有意义的事,而不是便宜行事。 5.如果可以的话,做个低调的行动者,而不是作秀者。 6.保持专注。 7.假设你聆听的对象知道一些你需求知道的事,耐心聆听,对方会愿意与你分享。 8.用心计划、经营、维持与伴侣之间的浪漫关系。 9.小心选择你分享好消息的对象。 10.小心选择你分享坏消息的对象。 11.让你去的每个地方,至少有一件事情变得更好。 12.尽情相像你想成为的样子,然后一心一意去实现它。 13.不要让自己变得傲慢或充满怨恨。 14.尽量让家里的某个房间变得漂亮。 15.跟昨日的自己相比较,别跟今日的别人相比较。 16.至少在一件事情上倾尽全力,看看会发生什么。 17.如果旧的的记忆仍然让你落泪,把它们仔细地、完整地写下来。 18.与他人保持联系。 19.不要随便贬低任何社会制度或艺术成就。 20.把自己当成某个你有责任照顾的人来对待。 21.请别人帮你个小忙,这样TA在未来也可以向你请求帮忙。 22.和真心希望你好的人做朋友。 23.不要试图拯救不想被拯救的人。 24.也不要轻易拯救向你求救的人。 25.没有一件圆满完成的事是无足轻重的。 26.批判世界之前先管好你自己的家(整顿好你的人生)。 27.让自己打扮成,你想成为的人的样子。 28.保持言辞精确。 29.站直,抬头挺胸。 30.不要回避阻碍你前行的障碍,尽管他很吓人。 31.不要做不必要的危险事情。 32.不要让你的孩子们做任何会让你讨厌他们的情事。 33.不要把你的妻子变成女佣。 34.不要把你不想看到的事情藏在迷雾之中。 35.当有人推卸责任时机会就会浮现了。 36.阅读伟大人物撰写的作品。 37.在街上遇到猫时,记得摸摸它。 38.孩子玩滑板时,不要打扰他们。 39.不要让仗势欺人的恶霸得逞。 40.如果你认为有什么需求改进的地方,请写信给政府,并提出解决方案。 41.记住,那些你还不知道的事比你已经知道的事来得重要。 42.即使受苦,仍要心存感恩。
View DetailsCentOS7开启防火墙及特定端口
开启防火墙服务 以前为了方便,把防火墙都关闭了,因为现在项目都比较重要,害怕受到攻击,所以为了安全性,现在需要将防火墙开启,接下来介绍一下步骤。 1, 首先查看防火墙状态:
|
1 |
firewall-cmd --state |
下图所示为关闭防火墙,接下来需要开启 2, 开启防火墙, 启动firewall:
|
1 |
systemctl start firewalld.service |
设置开机自启:
|
1 |
systemctl enable firewalld.service |
3, 重启防火墙:
|
1 |
systemctl restart firewalld.service |
4, 检查防火墙状态是否打开:
|
1 |
firewall-cmd --state |
如图显示已经打开 5, 查看防火墙设置开机自启是否成功:
|
1 |
systemctl is-enabled firewalld.service;echo $? |
如图所示,即为成功 以上就是开启防火墙相关步骤 开启特定端口 在开启防火墙之后,我们有些服务就会访问不到,是因为服务的相关端口没有打开。 在此以打开80端口为例 命令:
|
1 2 3 4 5 6 7 8 9 10 |
开端口命令:firewall-cmd --zone=public --add-port=80/tcp --permanent 重启防火墙:systemctl restart firewalld.service 命令含义: --zone #作用域 --add-port=80/tcp #添加端口,格式为:端口/通讯协议 --permanent #永久生效,没有此参数重启后失效 |
如图,可看到开启端口成功: 如果不放心,可以通过命令:
|
1 2 |
netstat -ntlp 或:firewall-cmd --list-ports |
查看开启的所有端口,具体如图 from:https://blog.csdn.net/zll_0405/article/details/81208606
View DetailsCentOS7安装PPTP服务器
1、安装PPTP
|
1 |
yum install pptpd ppp |
2、配置文件
|
1 2 |
#修改dns信息 vim /etc/ppp/options.pptpd |
将它更改为你的dns服务地址(此处为百度和谷歌的dns)
|
1 2 |
ms-dns 180.76.76.76 ms-dns 8.8.8.8 |
3、vpn 账户密码
|
1 |
vim /etc/ppp/chap-secrets |
设置 VPN账号 + 服务类型 + VPN密码 + IP
|
1 2 3 4 |
# Secrets for authentication using CHAP # client server secret IP addresses 123 pptpd 012345 * 456 * 123456 * |
账户123密码012345 4、设置最大传输单元
|
1 2 |
vim /etc/ppp/ip-up 在命令符 [ -x /etc/ppp/ip-up.local ] && /etc/ppp/ip-up.local “$@” 后面添加 ifconfig ppp0 mtu 1472 |
5、配置pptp配置文件
|
1 2 3 4 5 |
vim /etc/pptpd.conf localip 192.168.0.1 remoteip 192.168.1.100-110 localip ---本机ip地址 remoteip ---分配给客户端的地址,一般是内网网段地址 |
6、打开内核的ip 转发功能
|
1 2 3 |
vim /etc/sysctl.conf 编辑配置文件,添加 net.ipv4.ip_forward = 1 的配置,保存后退出。 运行 sysctl -p 使修改后的参数生效。 |
7、设置开机启动
|
1 2 3 4 5 |
#重启PPTP服务 systemctl restart pptpd #配置开机自启 systemctl enable pptpd.service |
8、打开防火墙
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
开启47及1723端口: firewall-cmd --zone=public --add-port=47/tcp --permanent firewall-cmd --zone=public --add-port=1723/tcp --permanent 允许防火墙伪装IP: firewall-cmd --zone=public --add-masquerade 允许gre协议: firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 0 -p gre -j ACCEPT firewall-cmd --permanent --direct --add-rule ipv4 filter OUTPUT 0 -p gre -j ACCEPT 设置规则允许数据包由eth0和ppp+接口中进出 firewall-cmd --permanent --direct --add-rule ipv4 filter FORWARD 0 -i ppp+ -o eth0 -j ACCEPT firewall-cmd --permanent --direct --add-rule ipv4 filter FORWARD 0 -i eth0 -o ppp+ -j ACCEPT 设置转发规则,从源地址发出的所有包都进行伪装,改变地址,由eth0发出:(192.168.0.0内网地址,子网地址前两位) firewall-cmd --permanent --direct --passthrough ipv4 -t nat -I POSTROUTING -o eth0 -j MASQUERADE -s 192.168.0.0/24 重启服务器: firewall-cmd --reload systemctl restart pptpd |
9、日志
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
1、上线日志 vim /etc/ppp/ip-up 在[ -x /etc/ppp/ip-up.local ] && /etc/ppp/ip-up.local "$@" 后加上 echo "$PEERNAME 分配IP: $5 登录IP: $6 登录时间: `date -d today +%F_%T`" >> /var/log/pptpd.log 2、下线日志 vim /etc/ppp/ip-down 在/etc/sysconfig/network-scripts/ifdown-post --realdevice ${REALDEVICE} \ ifcfg-${LOGDEVICE} 后加上 echo "$PEERNAME 下线IP: $6 下线时间: `date -d today +%F_%T`" >> /var/log/pptpd.log |
from:https://blog.csdn.net/h18733517027/article/details/94435182
View DetailsC#中TripleDES对应Java中的DESede即大家说的3DES,附C#及Java加解密结果一致的控制台程序例子
直接上代码了。 Java控制台代码: package Test; import java.security.Key; import javax.crypto.Cipher; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESedeKeySpec; import javax.crypto.spec.IvParameterSpec; import org.apache.commons.codec.binary.Base64; public class Test { private static final String encoding = "UTF-8"; public static void main(String[] args) { try { String text = "20200121";// 明文 String key = "Tt3rLPrDIVIhXqAz";// 长度控制为16,作为3DES加密用的key String encryptStr = EncryptData(text, key);// 3DES加密结果 System.out.println("明文:" + text); System.out.println("密钥:" + key); System.out.println("密文:" + encryptStr); System.out.println("解密:" + DecryptData(encryptStr, key)); } catch (Exception e) { e.printStackTrace(); } } /** * DESede加密,key长度为16 * * @param plainText 明文 * @param key 密钥 * @return DESede加密结果 * […]
View DetailswebAPI 使用注解非必须参数拦截问题
使用注解可以更方便对参数进行验证,但是也会存在非必须参数如:https://aaa.com?id=1&name=&age=;或https://aaa.com?id=1&name&age的请求。这时ModelState.IsValid过滤器将会拦截请求提示"值是必需的。"或"有一个值是必需的,但请求中不存在该值。"异常。 若接口使用model接收参数,可将值类型参数改为可空类型解决此问题;如:
|
1 |
int?id |
若接口不使用model接收参数,暂无没有找到解决方案; 经过调试可以使用一种笨拙的取巧方案解决:在过滤器.ModelState.IsValid==false内部对值的错误内容进行排除
|
1 2 3 4 |
if (Msg != "有一个值是必需的,但请求中不存在该值。" && Msg != "值是必需的。") { return; } |
from:https://blog.csdn.net/niuc321/article/details/88694793
View Detailsaxios基础用法
概述: 1.axios:一个基于Promise用于浏览器和nodejs的HTTP客户端。本质是对ajax的封装。 特征: 从浏览器中创建XMLHttpRequest 从node.js发出http请求 支持Promise API 拦截请求和响应 转换请求和响应数据 取消请求 自动转换JSON数据 客户端支持防止CSRF/XSRF 2.安装 npm install axios import axios from "axios" 3.API 1 axios(config)
|
1 2 3 4 5 6 7 8 |
eg: axios({ method:"post", url:"/user", data:{ firstName:"nanhua", lastName:"qiushui" } }); |
2.axios(url,config) //默认为get请求 3.请求方法别名
|
1 2 3 4 5 6 7 |
axios.request(config) axios.get(url,config) axios.post(url,data,config) axios.delete(url,config) axios.head(url,config) axios.put(url,data,config) axios.patch(url,data,config) |
4.并发
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
自定义配置创建axios实例 var instance = axios.create({ baseURL:"https://some-domain.com/api/", timeout:1000, headers:{"X-Custom-Header":"foobar"} }) 自定义实例默认值 //创建实例时设置 //实例创建后修改默认值(设置全局axios默认值) axios.defaults.baseURL = "https://api.example.com"; axios.defaults.headers.common['Authorization'] = AUTH_TOKEN; axios.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded"; 并发:axios.all(iterable) eg: axios.all([ axios.get("https://api.github.com/xxx/1"); axios.get("https://api.github.com/xxx/2"); ]).then(axios.spread(function(userResp,reposResp){ console.log("User",userResp.data); console.log("Repositories",reposResp.data); })) |
|
1 2 |
* 当所有的请求都完成后,会收到一个数组,它包含着响应对象,其中的顺序和请求发送的顺序相同,可以用<span class="hljs-selector-tag">axios</span><span class="hljs-selector-class">.spread</span>分割成多个单独的响应对象。 |
5.config参数
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
baseURL: 'https://some-domain.com/api/', //将自动加在url前面,除非url是一个绝对URL //允许在向服务器发送前,修改请求数据 //只能用在PUT\POST\PATCH //后面数组的函数必须返回一个字符串/ArrayBuffer或Stream transformRequest:[function(data){ //对data进行任意转换处理 return data; }], //在传递给then/catch之前,允许修改响应数据 transformResponse: [function (data) { return data; }], //即将被发送的自定义请求头 headers:{ 'X-Requested-With': 'XMLHttpRequest' }, //即将与请求一起发送的URL参数 params:{ ID: 12345 }, //负责params序列化的函数 paramsSerializer:function(params){ return Qs.stringify(params,{arrayFormat: "brackets"}); }, //超时 timeout: 1000, //表示跨域请求时是否需要使用凭证 withCredentials: false, //允许响应内容的最大尺寸 maxContentLength: 2000, //对打重定向数目 maxRedirects:5, //是否启用长连接 httpAgent: new http.Agent({ keepAlive: true }), httpsAgent: new https.Agent({ keepAlive: true }), //代理服务器设置 proxy:{ host:"127.0.0.1", port: 9000, auth:{ username:"nanhuaqiushui", password:"Huawei@123" } } |
6.响应结构
|
1 2 3 4 5 6 7 |
{ data:{}, status:200, statusText:"OK", headers:{}, //服务器响应的头 config:{} //为请求提供的配置信息 } |
7.拦截器
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
//请求拦截器 axios.interceptors.request.use(function(config){ //发送请求之前做些什么 return config; },function(error){ //请求错误之后做些什么 return Promise.reject(error); }) //响应添加拦截器 axios.interceptors.response.use(function(config){ //发送请求之前做些什么 return config; },function(error){ //请求错误之后做些什么 return Promise.reject(error); }) //移除拦截器 var myInterceptor = axios.interceptors.request.use(function(){ ... }) axios.interceptors.request.eject(myInterceptor); |
新兴实践
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
const service = axios.create({ baseURL: process.env.BASE_API, timeout: 100000 }) // 请求拦截器 service.interceptors.request.use( config => { config.headers['Content-Type'] = 'application/json' if (store.getters.token) { // 让每个请求携带token config.headers['Authorization'] = store.getters.token } return config }, error => { Toast.failed('网络异常,请检查网络连接') console.log(error) // for debug return Promise.reject(error) } ) // 响应拦截器 service.interceptors.response.use( response => { const res = response.data if (res.code && res.code !== 200) { Toast.failed(res.message) } return response }, error => { Toast.failed('网络异常,请检查网络连接') return Promise.reject(error) } ) export default service |
from:https://www.cnblogs.com/nanhuaqiushui/p/10514122.html
View Detailsvue中$emit与$on和BUS
bus: //vue原型链挂载总线 Vue.prototype.bus = new Vue(); //子组件发送数据 this.bus.$emit("change",data); //子组件接收数据 this.bus.$on("change",function(data){ }) vue中$emit与$on var Event = new Vue(); 相当于又new了一个vue实例,Event中含有vue的全部方法; Event.$emit('msg',this.msg); 发送数据,第一个参数是发送数据的名称,接收时还用这个名字接收,第二个参数是这个数据现在的位置; Event.$on('msg',function(msg){ 接收数据,第一个参数是数据的名字,与发送时的名字对应,第二个参数是一个方法,要对数据的操作 /这里是对数据的操作 }) 例:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>孙三峰--博客园</title> <script type="text/javascript" src="js/vue2.0.3.js" ></script> <script type="text/javascript"> //准备一个空的实例对象 var Event = new Vue(); var A={ template:` <div style="border: 1px solid red; margin-bottom: 10px; width: 300px;"> <h4>A组件</h4> <p>{{a}}</p> <input type="button" value="把A数据给C" @click="send" /> </div> `, data(){ return { a:'我是A里面的数据' } }, methods:{ send(){ //A发送数据 Event.$emit('a-msg',this.a); } } }; var B={ template:` <div style="border: 1px solid green; margin-bottom: 10px; width: 300px;"> <h4>B组件</h4> <p>{{b}}</p> <input type="button" value="把B数据给C" @click="send" /> </div> `, data(){ return { b:'我是B里面的数据' } }, methods:{ send(){ Event.$emit('b-msg',this.b); } } }; var C={ template:` <div style="border: 1px dotted green; margin-bottom: 10px;width: 300px;"> <h4>我是C组件,我在坐等接收数据</h4> <p>{{a}}</p> <p>{{b}}</p> </div> `, data(){ return{ a:'', b:'' } }, mounted(){ //两种接收的方式 var _this = this; Event.$on('a-msg',function(a){ _this.a=a; }); Event.$on('b-msg',function(b){ this.b = b; }.bind(this)) } }; window.onload=function(){ new Vue({ el:'#box', data:{ }, components:{ 'com-a':A, 'com-b':B, 'com-c':C } }) } </script> </head> <body> <div id="box"> <com-a></com-a> <com-b></com-b> <com-c></com-c> </div> </body> </html> |
效果图: from:https://www.cnblogs.com/wang-sai-sai/p/11158770.html
View DetailsPHP:cURL error 60: SSL certificate unable to get local issuer certificate
导致该问题的原因在于没有配置curl.cainfo,该配置位于php.ini中。 解决方案: 1)下载cacert.pem https://curl.haxx.se/ca/cacert.pem 2)配置php.ini [curl] ; A default value for the CURLOPT_CAINFO option. This is required to be an ; absolute path. curl.cainfo = 【你的绝对路径】 ———————————————— 版权声明:本文为CSDN博主「loophome」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/loophome/java/article/details/83112364
View Detailsasp.net获取IP
|
1 2 3 4 5 6 7 8 9 10 11 12 |
/// <summary> /// get ip /// </summary> /// <returns></returns> public static string GetIp() { var context = HttpContext.Current; return context.Request.ServerVariables["HTTP_X_REAL_IP"] ?? context.Request.ServerVariables["HTTP_X_FORWARDED_FOR"] ?? context.Request.ServerVariables["REMOTE_ADDR"] ?? "unknow"; } |
View Details