玲弟啊玲弟的博客

个人博客


  • 首页

  • 标签

  • 分类

  • 归档

新华三面试-2019-03-21

发表于 2019-03-27 | 分类于 面试 | 阅读次数:
字数统计: 1.3k 字 | 阅读时长 ≈ 4 分钟

新华三面试

在51job上更新了自己的简历,忘记有没有投新华三的岗位了,接到了新华三的面试邀请。电话里问我是不是投了他们的测试岗,要不要来面试,有点懵逼,我说我投的是开发岗位(我也不记得我投了没有了,后来看自己的投递岗位确实没有找到这个投递,就补了上去),他说确认一下,就说有的有的,问我什么时候来面试。于是约到两天后。吐槽一下办事效率,说发面试邮件给我,过了两个小时没有收到(正常企业HR说发面试邀请基本上都是秒发),我以为我的gmail有问题或者发错邮箱了,于是我打电话回去问,对面那边说:”我已经让秘书发了,不行我再催催“。wtf,秘书?道谢之后也不敢再催,又等了一个多小时,终于看到了面试邀请。但是进入新华三领临时来宾卡的短信,我却是面试当天的上午才收到,电话里没有沟通清楚,给我约在了5点,我打电话问的改在了三点钟,基本上随到随考把。面试先到前台领的试卷,填个人基本信息,家庭信息(家里有没有人在h3c等),曾任职公司,项目经历,最后才是一套考试题。我自己是一年经验,试卷题目也比较简单。分20道不定项选择题 + 4道 简答题。

###选择题

20道不定向选择题:

(1) 以下哪些可以修饰是 2.15

double Double Float float

(2)以下哪些可以修饰接口

A protect B public C private D default

(3)java 中final 可以修饰哪些

A 接口 B 成员变量 C 方法 D 类

(4) 以下哪些是 Thread 的 方法

A run B start C exit D hasPriority

(5) 下面程序输出的结果是什么

public class Example {
String str=”good”; char[] ch={‘a’,’b’,’c’};

    public static void main(String[] args){

         Example ex = new Example();
         ex.change(ex.str,ex.ch);
         System.out.print(ex.str + "and ");
         System.out.println(ex.ch);
}     public void change(String str,char[] ch){
         str = "test ok";
         ch[0]='g';
}

}

(6)java 靠 _ 实现线程间的同步

A jvm B cpu C.. D

(7)

简答题

简述springmvc 流程

error与exception的 区别

简述线程同步的方法

一面

一个年轻小伙子给我面试的,看起来也不是很厉害。问了一些线程同步,eureka原理,kubernetes 架构简单的说了一下。

二面

项目面试,一个女面试官,就对着项目问,问为什么这么做,有没有更好的解决方法等,当时也是随便扯的,她整体上有个认识,但是面试官好像对技术不太行。也问了项目中觉得最难的部分是什么,全程盯着我的眼睛很认真的听,人还是很好的。面试官对容器对业务还是有一定了解的,但是对具体技术就一般般了。

三面

HR 不面试的时候hr还是挺好的,开始面试以后Hr就比较认真了,还是那些,为什么离职,新工作选择主要因素,以前最大的挑战,平时在学习或者在看的东西。问了下薪资构成,她说薪酬老板面,会跟我谈

四面

老板来了,等了我20分钟,手机差点没电,在新华三的食堂。很尴尬,大家都在吃饭,而我在等人。简单聊了一下,谈了以下薪资,一路都在夸新华三还是很不错的,便宜的食堂,健康的饭菜,说两周左右出结果,然后会有个心里测评,可以的话就隔天把我资料交上去。后来一起在食堂吃了晚饭,也一直在夸新华三的好,项目不错,扁平化管理balabala的,踩了社会很多坑的我心里还是设了一道防线的。吃饭的时候聊聊他们在做的项目,聊一下微服务,感觉也是瞎扯把,说的话好像都在某些博客里看到过,莫不是大家都是看了点博客就当成自己的感悟开始吹嘘了。因为我的期望薪资和他给的还是有一点点差距,最后走的时候还跟我说,就不要在意那点钱了,帮我争取但是不要在意工资这个事情。老板口头上是给了offer了,ps : 新华三招人 学历还是挺重要的。

总结

暂时还没有入职,在等消息,很煎熬,全程秘书电话联系,但是秘书我是没简单,hr电话没有,老板电话有,名字都忘了问了,让我很难安。网上说流程都是很长的,希望等待是值得的吧,老板都叫我来干活了,offer要是被鸽了真的是心态爆炸,目前已经离职,准备出去玩轻松一下,毕竟刚从上一家公司的坑里跳出来。

关于devops环境迁移出现的问题

发表于 2019-03-04 | 分类于 devops | 阅读次数:
字数统计: 315 字 | 阅读时长 ≈ 1 分钟

关于devops环境迁移出现的问题

锁问题:

在做迁移环境的测试的时候,将gerrit,gitlab,jira等服务的挂载卷copy到同一网段的另一个k8s集群中,出现大量程序锁,目录锁的问题,程序或者目录已经有另一个实例启动或者目录已被使用,不建议暴力迁移,直接将volume复制出来,要么在不同网段,即使这样,也有存在一些问题。

解决:

目录锁。jira出现的,jira-home 被使用,只需要将jira-home下的隐藏文件jira-home.lock 删除,重启服务即可。注意,要暂停服务,然后再删除,再重启服务。即使停掉测试服务,也还是会出现这个问题,根除方法暂为找到。

程序锁。gerrit 出现,看起来想是索引文件锁,但是删除锁文件不成功,暂停服务,剪切索引文件再复制回去,就莫名其妙的好了。使用之前备份的索引文件也能成功。

gitlab 不能读取到仓库数据的问题

gitlab 迁移会出现,其他数据都正常,唯独仓库底下的代码没有加载进来,试过一些方法也没解决。

配置中心Apollo

发表于 2019-03-03 | 分类于 微服务 | 阅读次数:
字数统计: 1.9k 字 | 阅读时长 ≈ 7 分钟

@TOC

关于Apollo

Apollo(阿波罗)是携程框架部门研发的分布式配置中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置管理场景。

github地址:https://github.com/ctripcorp/apollo
在官方的wiki 里,有很多资料,包括部署 客户端应用等
github wiki 地址:https://github.com/ctripcorp/apollo/wiki

Apollo 与 Springcloud config

Apollo 是携程框架研发部门研发的一款基于springboot和springcloud 写的一个配置中心项目,使用长连接实现配置下发,现在已经开源,可以秒级感应热部署配置文件。

Springcloud Config 是springcloud 全家桶里的一员,基于git 做的配置中心,对于热部署配置文件来说,还需要配合 git 的webhook 触发 springcloud bus,达到配置下发,从实现机制来说,Apollo 是要快上许多。而完全依赖于git 的config 不仅配置麻烦,而且感觉会很low。

先说一下我的使用感受,部门里一个微服务支付的项目用的就是springcloud config 配置中心

优点:

  1. 基于git(当然svn,jdbc,本地缓存也支持),对于github 或者 gitlab 来讲比较熟悉,git的优点可以应用于配置文件上
    2.配置文件管理一幕了然,公有的配置文件或者项目私有的配置,按照规范填写,分类后比较好找,按照项目,按照模块建包,一目了然
    3…. (我是个不善于总结优点的人)

来说说缺点:

  1. 如果要实现热部署配置文件,需要配合springcloud bus,在github上做webhook ,依赖性很强,配置复杂,实时性也一般,不做热加载的配置下发,那配置中心将毫无意义。
    2.配置复杂意味着,且对代码有侵入,学习成本高,个人不是很喜欢。
    3.配置文件命名规则,很麻烦,配置都在命名上,根据命名搜索,没有可视化的配置
    4.权限控制,配置下发基于git的权限,也是成也git 败也git ,不能很好掌控配置下发的权利
    5.不支持多语言客户端,全家桶的问题
    6….(我还是个不善于总结缺点的人)

关于Apollo ,使用感受非常爽,先吹他一个彩虹屁。
优点:

  • 无需过多的依赖,原生java,.net 都很好应用,多语言客户端无需过多的依赖,原生java,springboot,.net 都很好应用,多语言客户端
  • 依赖少,不基于git,部署简单,即能实现动态加载配置,客户端配置也简单
  • 可视化操作,权限控制,都让人很爽
  • 多环境支持,可以 dev fat uat pro,提供分布式部署

缺点:

  • 可能还是使用太少,项目一多,文件数量一多,文件关系一复杂,配置起来比较头晕目眩,查找项目也比较难找
  • 本来以为上面这个是缺点,但是写着写着想到了还是好管理的,否认了我自己,写文章的时候没有参考很多,只是把自己想到的记录下,以后会补充,有很多不正确的地方,也需要读者多多指教。保持着尽量严谨和实践证实的心态写文章。

Apollo的部署

多环境部署

首先是使用多环境部署,关于Apollo 的环境,支持dev,fat,uat,pro 四种部署环境。

Apollo 包括 服务端,页面前端 与 自己的客户

每一个环境就是一个服务端,前端页面portal 可以集成多个环境,多环境就是比单环境多增加了几个服务端罢了。

如果只想建单环境,起一个服务端即可。

例如
单环境:
在192.16.35.11 上部署dev 的服务端(Apollo-adminserver + Apollo-configserver+portal)

多环境:
在192.16.35.11 上部署dev 的服务端(Apollo-adminserver + Apollo-configserver)
在192.16.35.12 上部署pro 的服务端(Apollo-adminserver + Apollo-configserver)

最后在生产的机器192.16.35.12 上配置 前端页面服务就行 (Apollo-portal)

源码编译方式传统部署(多环境)

==部署环境:==
maven 3.3.9
jdk 1.8
Apollo v0.11.0
dev 服务器 192.16.35.10 (admin-server 与 config-server)
pro 服务器 192.16.35.11(admin-server , config-server,portal)

下载项目源码

v1.0.0 之后是用springboot 2.0 写的,而我们自己还是1.5.10
官方文档部署里有声明springboot的某些配置需要v0.10.0 之后
所以这里选了v0.11.0 版本
下载地址:https://github.com/ctripcorp/apollo/releases
自己选择脚本下载tar.gz 的包

然后上传到linux 服务器上,这里采用的是RedHat7.4,centos同理

1
tar xvf apollo-0.11.0.tar.gz

解压到自己的服务器上。
在这里插入图片描述
会看到如下项目路径,windows 使用idea 打开也行

执行数据库sql

进入scripts 文件夹 里面有个sql 文件,一个是configdb 服务端的sql,一个是portaldb 的sql,每一个服务端需要一个configdb,如果没有多个mysql服务,暂时建在同一个mysql服务下,但是要修改configdb的数据库名字

以下两处 ApolloConfigDB 改为 ApolloConfigDB2
在这里插入图片描述
这样在你的mysql 上应该有一个==ApolloConfigDB== 一个==ApolloConfigDB2== 一个==ApolloPortalDB== 三个数据库

分别对应dev环境的数据库 pro 环境的数据库 和 portal 的数据库

修改build 配置文件,编译项目

在刚刚的sql 同级目录下,有个build.sh 。 windows用bat
修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/bin/sh

# apollo config db info
apollo_config_db_url=jdbc:mysql://your-mysqldb:port/ApolloConfigDB?characterEncoding=utf8
apollo_config_db_username=root
apollo_config_db_password=******

# apollo portal db info
apollo_portal_db_url=jdbc:mysql://your-mysqldb:port/ApolloPortalDB?characterEncoding=utf8
apollo_portal_db_username=root
apollo_portal_db_password=******

# meta server url, different environments should have different meta server addresses
dev_meta=http://dev:8080
#fat_meta=http://fill-in-fat-meta-server:8080
#uat_meta=http://fill-in-uat-meta-server:8080
pro_meta=http://fill-in-pro-meta-server:8080

META_SERVERS_OPTS="-Ddev_meta=$dev_meta "

# =============== Please do not modify the following content =============== #

这个就很明白了
dev 服务器上不启动portal ,不需要修改portal 的信息,只需要修改apollo config db 的数据库连接信息,连接到 apollo config db

pro 服务器上需要启动portal ,则需要修改portal 的db 信息,注意修改这里apollo config db 的数据库名字已经变成 ApolloConfigDB2了,
另外 meta server 不建议使用8080 端口,可以改为其他,如7070
dev_meta ip 用dev环境的 ip
pro_meta 使用localhost即可
META_SERVERS_OPTS 使用了哪几个环境就填哪几个

1
2
3
4
5
6
7
# meta server url, different environments should have different meta server addresses
dev_meta=http://192.16.35.10:7070
#fat_meta=http://fill-in-fat-meta-server:8080
#uat_meta=http://fill-in-uat-meta-server:8080
pro_meta=http://localhost:7070

META_SERVERS_OPTS="-Ddev_meta=$dev_meta -Dpro_meta=$pro_meta "

最后两台服务器分别执行 ./build.sh 编译源码

启动服务

第一次编译需要点时间

编译完成后,在各个项目下会出现target文件,里面有个zip文件夹
例如: apollo-adminservice-0.11.0-github.zip
在这里插入图片描述

这里只需要关注三个项目,圈圈出来的
在这里插入图片描述

在dev服务器下 解压 adminservice 和configservice
在pro服务器下 解压adminservice 和configservice,portal
解压到test文件夹下

1
unzip apollo-adminservice-0.11.0-github.zip -d test

解压完毕后启动项目,在解压出来的test下有个script文件夹,里面有启动脚本

1
./startup.sh

注意的是 adminservice 直接启动,configservice 刚刚修改了端口7070,需要修改startup.sh 里的端口设置

1
SERVER_PORT=7070

portal在启动前修改数据库参数,apollo.portal.envs value 改为 dev,pro 有多个环境的,直接 逗号然后加上去就行,然后启动portal,打开192.16.35.11:8070 (pro服务器:port),登录用户/密码 apollo/admin

在这里插入图片描述

springboot 客户端demo (待续)

Docker or Kubernetes 方式 (待续)

写博客的目的

发表于 2019-03-03 | 分类于 随笔 | 阅读次数:
字数统计: 159 字 | 阅读时长 ≈ 1 分钟

写博客的目的

这个放在前面,提醒自己。

做一件事情,不能太功利,做一件事情,要想清楚,是自己想要做,还是不得不做,还是说做给别人看

我写博客 一是为了技术的沉淀,很久以后回头一看,原来自己会的那么多呢

二是为了提醒自己,做程序员是自己想做,而不只是为了一份工作,不然工作也太煎熬了

三是提升写作和表达能力,总结能力,我也喜欢有感而发,从骨子里觉得自己应该是个文青

分布式事务浅析

发表于 2019-03-03 | 分类于 微服务 | 阅读次数:
字数统计: 329 字 | 阅读时长 ≈ 1 分钟

分布式事务

摘要: 在做单体服务的微服务改造时,碰到的问题,大多数时候,使用本地事务就可以了,在业务拆分的时候也尽量避免了分布式事务,但是不免遇到分布式事务的情况。就稍微看了一些关于分布式事务的东西。文章写的好的人很多,我会把参考的文章放在底部,本文是自己对分布式事务的一个概括总结。

什么是分布式事务?

分布式事务是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。简答的打个比方说就是,A 服务的一个方法里同时调用B,C 服务拥有事务的方法,要同时保证B,C 都正确执行或者B,C全部回滚。本质上来说,分布式事务就是为了保证不同数据库的数据一致性。

对于分布式事务的理论和实现方式,下面的文章总结的比较好

参考文章: https://juejin.im/post/5b5a0bf9f265da0f6523913b#heading-14

  • 基础理论: CAP理论,BASE理论
  • 分布式事务模型: 2PC,3PC,TCC,Saga,MQ

devops自动化流水构建(gitlab+gerrit+jenkins+sonar)

发表于 2019-03-03 | 分类于 devops | 阅读次数:
字数统计: 934 字 | 阅读时长 ≈ 3 分钟

devops 自动化流水构建(gitlab+gerrit+jenkins+sonar)

摘要:关于当下较为流行的devops概念,有了docker 容器之后,才能够真正的让开发人员快速和方便的掌握服务运维的方式,并且用搭建自动化流水构建,节省许多运维成本和开发效率。本文介绍主要架构及部署方式,是以自己公司的实战经验为总结,不一定很准确,但是能够提供一个大致的方向。

什么是devops?

按照惯例,先介绍概念。

DevOps(Development和Operations的组合词)是一种重视“软件开发人员(Dev)”和“IT运维技术人员(Ops)”之间沟通合作的文化、运动或惯例。透过自动化“软件交付”和“架构变更”的流程,来使得构建、测试、发布软件能够更加地快捷、频繁和可靠。

来自wiki百科:https://zh.wikipedia.org/wiki/DevOps

最重要的一点就是,通过自动化的发布,使得开发与运维人员可以更加敏捷和频繁的发布应用。

如何做到自动化发布,就是今天的内容。

自动化流水持续集成的架构

devops架构

这是当前较为主流的方案,也是我们公司近两年一直在使用的

  • gitlab : 私有化的gitlab 代码仓库,拥有私有化的代码仓库是最基础的一步。
  • gerrit: gerrit 做代码审查,每个成员往gitlab提交的代码,需要codereview权限和verify 权限的人同意才能往分支上推送,质量差或者有问题的代码可以及时退回,开发人员提交代码的时候更加的谨慎,保护代码质量
  • jenkins: 代码合格后,通过jenkins的持续集成,定时或者手动或者触发器的方式,将代码构建成镜像文件,最后通过脚本部署到docker服务器或者kubernetes集群中
  • sonar: 与阿里巴巴代码规范检查插件一样,jenkin构建后会将代码推送至sonar服务器,评审代码的质量,也可以自定义代码规范

通过以上的步骤,全部自动化直到镜像的构建和应用的发布,无需运维人员参与,即可完成应用发布,减少很多重复的劳动和时间。

简单部署和注意事项:

所有k8s的部署文件yaml,放在github上,docker部署都比较简单

  • gitlab部署: 注意事项,三个挂载卷必须挂在,不然数据丢失或者各种问题,三个开发端口,443,80,22

    对应的映射端口可以自己选择,80对应web端口,22对ssh端口,即提交或者clone使用端口,443就是https

    我们使用的是ce版本 9点多,较老,数据迁移时,需要一样的版本才行,选择版本看情况

    镜像下载地址:https://hub.docker.com/r/gitlab/gitlab-ce

  • gerrit 部署: 直接启动没什么好说,如何要和gitlab做同步,需要使用replication插件,replication文件修改,在gitlab上注册一个gerrit用户,配上gerrit公钥,执行同步,可以参考我的另一篇文章

    xxxxxxx

  • jenkins部署:docker单机启动问题不大,在kubernetes上的话,build任务执行,需要新建一个building job pod ,直接挂载 pod所在node的docker.sock文件 运行build任务,相当于在容器里执行容器,具体的看我的yaml文件如何写,如果需要配置sonar,则需要sonar插件,在jenkins构建后执行推送至sonar服务器评审。

    参考文章: xxxxxxxx

  • sonar部署:配置不多,就是最好学会自定义代码检查规则的做法

    参考文章: xxxxxxxx

eureka浅析

发表于 2019-03-03 | 分类于 微服务 | 阅读次数:
字数统计: 2.1k 字 | 阅读时长 ≈ 8 分钟

netfix eureka 浅析

摘要: 网上关于eureka 的介绍很多,也有很多优秀的文章可以作为参考,在文章末尾我会贴上自己看过觉得有收获或者总结性强的文章。主要内容会简单介绍 eureka 整体的架构和原理,部分代码实现,以及配置参数列表和一些注意事项。

什么是eureka?

Eureka是一种基于REST(Representational State Transfer)的服务,主要用于AWS云,用于定位服务,以实现中间层服务器的负载平衡和故障转移。我们将此服务称为Eureka Server。Eureka还附带了一个基于Java的客户端组件Eureka Client,它使与服务的交互变得更加容易。客户端还有一个内置的负载均衡器,可以进行基本的循环负载均衡。在Netflix,一个更复杂的负载均衡器包含Eureka基于流量,资源使用,错误条件等多种因素提供加权负载平衡,以提供卓越的弹性。

本文以官方wiki为主要参考,wiki: https://github.com/Netflix/eureka/wiki/Eureka-at-a-glance

这段是官方的翻译,说白了,就是我们现在使用的微服务架构中的注册中心,server端是一个服务注册信息中心,client端则作为信息的消费者和提供者。类似的注册中心 还有consul,zookeeper,etcd 等都可以作为注册中心,官方宣布 eureka2.x disconnected 之后,consul 或称为主流的替代方案。

eureka 原理及架构

官方架构图:https://github.com/Netflix/eureka/raw/master/images/eureka_architecture.png

服务在Eureka 注册,然后发送心跳每30秒更新一次租约。如果客户端无法续订租约几次,则会在大约90秒内将其从服务器注册表中删除。注册信息和续订将复制到群集中的所有eureka节点。来自任何区域的客户端都可以查找注册表信息(每30秒发生一次)以查找其服务(可能位于任何区域中)并进行远程调用。

eureka 一些概念及部分源码分析

在架构中可以得知,分为以下几个部分:

高可用框架使用的是三个server,两两注册的方式。

  • register 注册 :client 启动后发起注册,netflix源码是从第一次发起心跳(30s后)发生注册,springcloud 更改过设置,在client启动时就发起注册。 在 eureka-client 里的discoveryclient类中有一个register()法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    boolean register() throws Throwable {
    logger.info(PREFIX + "{}: registering service...", appPathIdentifier);
    EurekaHttpResponse<Void> httpResponse;
    try {
    httpResponse = eurekaTransport.registrationClient.register(instanceInfo);
    } catch (Exception e) {
    logger.warn(PREFIX + "{} - registration failed {}", appPathIdentifier, e.getMessage(), e);
    throw e;
    }
    if (logger.isInfoEnabled()) {
    logger.info(PREFIX + "{} - registration status: {}", appPathIdentifier, httpResponse.getStatusCode());
    }
    return httpResponse.getStatusCode() == Status.NO_CONTENT.getStatusCode();
    }

    这里小小吐槽一下,logger.info 竟然 用了 isInfoEnabled() 判断,有些多余,这个原则是为了 减少 字符串 + 操作可能带来多余的性能复合,但现在用了通配符 {} ,在logger.info 的实现中已经使用 isInfoEnabled 方法来避免了。但是源码里经常这样写,可能是为了保险?

    往下追踪eurekaTransport.registrationClient.register 方法可以发现,底层是使用 Jersey 实现了自己的eurekahttp 封装,jersey (一个 Java restful 框架) 还没有使用过,有空去研究一下。

    往上追踪呢发现 register 方法是在一个 InstanceInfoReplicator类 ,继承了runnale 是一个定时任务,二这个定时任务在@inject DiscoveryClient 的时候就执行了initScheduledTasks() 方法,在这个方法内开启了这个定时任务。

  • renew 续约 :client 每30s 发生一次http请求,及上面提到的定时任务,来告诉server端,我依旧存活着。renew() 方法 与 register() 类似,都在 discoveryclient类中。服务端的续约接口自,eureka-core中的 com.netflix.eureka包下的InstanceResource类下,接口方法为renewLease(),追踪源码可以看到 心跳间隔是30s,剔除服务心跳超时时间是90s

    可以通过设置参数来改变时间间隔,官方建议是谨慎改变这个时间

    1
    2
    eureka.instance.leaseRenewalIntervalInSeconds
    eureka.instance.leaseExpirationDurationInSeconds
  • getRegistery 得到服务 : client 获得server端的 实例信息,同上,有一个fetchRegistry() 和 getApplications() 的方法,客户端想要获得应用可以使用getApplication方法,会从本地缓存中获得应用,本地缓存使用,AtomicReference localRegionApps 来保存对象,保证线程安全。大量使用了这个。而 fetchRegistry() 方法则是 重新获得server端 register信息,并且更新本地缓存和远端服务端中该服务的状态。

  • cancel 服务下线 : 类似上面,使用的unregister() 方法。在@PreDestroy shutdown方法中调用,则是在服务关闭或者意外崩溃时,调用注销方法,包括关闭定时任务,更改自身服务状态,再向server端发送最后一次http请求。

  • replicate:这里我理解为实例信息在服务端间的同步,在eureka-core 中PeerEurekaNodes 类有写,每隔10分钟更新集群节点,每隔一分钟统计最近一分钟内所有Client的续约次数,也就是接收到的心跳次数,以此来作为是否触发服务信息回收的依据之一,EurekaServer每隔60S执行一次服务信息的回收,每隔30S执行一次,更新只读响应缓存,具体代码分析参考下面的文章。

    eureka-server peer同步: https://blog.csdn.net/qq_27529917/article/details/80934523

eureka 的相关注意事项和问题

  • Eureka的几处缓存 (三处缓存,一处延时)

    服务启动后最长可能需要2分钟时间才能被其它服务感知到,

    1. eureka-server http缓存,server端相应getApplication 从缓存中拿取

      eureka-server 的缓存:

      对于client的http请求,server端利用两个map做缓存,一个是readWriteCacheMap 一个是readOnlyCacheMap ,先请求readOnlyCacheMap ,若数据与 readWriteCacheMap ,则同步readWriteCacheMap 的数据,若readWriteCacheMap 还是没有,则直接从内存 registry 中获取,readOnlyCacheMap 缓存30s 定时器更新,readWriteCacheMap 缓存180s 定时器更新

      源码分析参考: https://www.jianshu.com/p/ae4f0c8b8135

    2. eureka-client 对获取到的服务(30s更新)做了本地缓存,默认从本地缓存中读取 ,

    3. 负载均衡的ribbon 30s缓存,缓存 eureka-client 服务列表

    4. 启动延迟注册,需要等30s 后,发起心跳请求才注册

  • 服务注册信息不会被二次传播

    如果Eureka A的peer指向了B, B的peer指向了C,那么当服务向A注册时,B中会有该服务的注册信息,但是C中没有。需要全部写在 peer 里

  • 多网卡环境下的IP选择问题

    如果服务部署的机器上安装了多块网卡,它们分别对应IP地址A, B, C,此时:
    Eureka会选择IP合法(标准ipv4地址)、索引值最小(eth0, eth1中eth0优先)且不在忽略列表中(可在application.properites中配置忽略哪些网卡)的网卡地址作为服务IP。
    这个坑的详细分析见:http://blog.csdn.net/neosmith/article/details/53126924

  • Eureka 的自我保护模式

    如果有任何时间,Eureka Serve接收到的续约低于为该值配置的百分比(默认为15分钟内低于85%),则服务器开启自我保护模式,即不再剔除注册列表的信息。

    ​

以上问题的答案,在我参考的文章底部有,也是常见的一些问题。

https://blog.csdn.net/fanhenghui/article/details/77008733

https://blog.csdn.net/forezp/article/details/73017664

生产上的eureka配置(仅参考)

server端配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
## 中小规模下,自我保护模式坑比好处多,所以关闭它
eureka.server.enableSelfPreservation=false
## 心跳阈值计算周期,如果开启自我保护模式,可以改一下这个配置
## eureka.server.renewalThresholdUpdateIntervalMs=120000

## 主动失效检测间隔,配置成5秒
eureka.server.evictionIntervalTimerInMs=5000

## 心跳间隔,5秒
eureka.instance.leaseRenewalIntervalInSeconds=5
## 没有心跳的淘汰时间,10秒
eureka.instance.leaseExpirationDurationInSeconds=10

## 禁用readOnlyCacheMap
eureka.server. useReadOnlyResponseCache=false

client 端配置

1
2
3
4
5
6
7
8
9
## 心跳间隔,5秒
eureka.instance.leaseRenewalIntervalInSeconds=5
## 没有心跳的淘汰时间,10秒
eureka.instance.leaseExpirationDurationInSeconds=10

# 定时刷新本地缓存时间
eureka.client.registryFetchIntervalSeconds=5
# ribbon缓存时间
ribbon.ServerListRefreshInterval=2000

主要针对缓存时间的配置,心跳缩短的弊端就是,在自我保护机制阈值的计算时候,按照每分钟计算,如果时间缩短为一倍,失败时候就会多一倍的计算,需要调整阈值,根据实际场景调试等,还有就是server的缓存机制太多层,详情看以下博客。

https://www.jianshu.com/p/6ac4810f6f42

Xshell登录Vagrant方式

发表于 2018-12-01 | 分类于 k8s | 阅读次数:
字数统计: 406 字 | 阅读时长 ≈ 1 分钟

Xshell登录Vagrant方式

我上一篇文章 介绍了vagrant 如何创建虚拟机集群,在上篇文章的基础上,用xshell 登录 虚拟机发现 默认是无法使用账号密码登录root账号,只能使用vagrant账号,密码vagrant,

vagrant账号登录

在虚拟机 vagrantfile 的目录位置 打开控制台,输入vagrant ssh-config

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ vagrant ssh-config

Host k8s-m1
HostName 127.0.0.1
User vagrant
Port 2222
UserKnownHostsFile /dev/null
StrictHostKeyChecking no
PasswordAuthentication no
IdentityFile D:/vagrant-file/file1/.vagrant/machines/k8s-m1/virtualbox/private_key
IdentitiesOnly yes
LogLevel FATAL

Host k8s-n2
HostName 127.0.0.1
User vagrant
Port 2200
UserKnownHostsFile /dev/null
StrictHostKeyChecking no
PasswordAuthentication no
IdentityFile D:/vagrant-file/file1/.vagrant/machines/k8s-n2/virtualbox/private_key
IdentitiesOnly yes
LogLevel FATAL

查看 hostname ,port,IdentityFile 这三个位置

xshell登录

有可能不能选择密码登录,默认是用密钥登录,浏览,文件,找到 刚刚的IdentityFile ,再输入密码vagrant 就可以使用vagrant 用户 ssh登录

root账号登录

vagrant登陆后,切换到root账号

1
$ sudo -i

设置root的密码
在这里插入图片描述
修改 /etc/ssh/sshd_config 文件,(注意,vagrant用户下这个文件是只读的,可能什么也看不见)
修改 ssd_config 里 PermitRootLogin属性 改为yes ,并把前面的# 去掉
在这里插入图片描述

PasswordAuthentication 改为yes 并且去掉 #
在这里插入图片描述

保存退出,重启sshd服务

1
$ systemctl restart sshd

再通过xshell连接的时候,就可以用账号密码,root来登录了

问题:虽然xshell里都是用127.0.0.1:2222或者2200 这种登录的,但是也可以使用自己设置的ip 例如192.16.25.11:22 去登录,这里用自己设置的ip时端口则是22。
设置完成以后就和自己开的虚拟机没什么两样了。

k8s搭建之初始环境准备-虚拟机篇(一)

发表于 2018-12-01 | 分类于 k8s | 阅读次数:
字数统计: 1.5k 字 | 阅读时长 ≈ 6 分钟

k8s搭建之初始环境准备-虚拟机篇(一)

我相信很多搭建k8s 集群的小伙伴最头疼的一件事情就是,我没有那么多机器啊,别说高可用,就算是一个master一个node 用VM都烦的很,安装的哪个图形化就要点老半天,snapshot 快照要是没有准备,环境搞得乱七八糟,那真的是心态爆炸,遇上重装,拜拜了您勒。
如果有钱就去搞个阿里云,什么什么云的服务器,租个三个月好好搞(ps : 不要为了省钱,像博主一样,几个账号各自买esc,不同租户网络是隔离的,对于网络互通的k8s来说比较不友好,搭建成功以后会各种服务访问失败,而且不同云服务商的网络也是不一样的,有的可能有解决方案对于跨租户VPC互通,有点就麻烦,不要得不偿失了)
公司有服务器让你用就另说了,物理机的话也是难受的一批,类似openstack的解决方案是最好的。
当然如果你什么都没有怎么办呢,本地虚拟机还是最好的学习手段。本文用vagrant + vistualbox,快速生成本地虚拟机环境,以及一些可能我自己遇到的坑。文章可能比较长,比较繁琐,多比较几篇文章,多操作,每个人都可以总结出自己的经验来。

下载安装 vagrant

什么是vagrant

Vagrant是一款用于构建及配置虚拟开发环境的软件,基于Ruby,主要以命令行的方式运行。主要使用Oracle的开源VirtualBox虚拟化系统,与Chef,Salt,Puppet等环境配置管理软件搭配使用, 可以实行快速虚拟开发环境的构建。
早期以VirtualBox为对象,1.1以后的版本中开始对应VMware等虚拟化软件,包括Amazon EC2之类服务器环境的对应。
vagrant 是支持win10的 hyper-v 的,但是这次还没试用,还是用的virtualBox 。

下载安装vagrant

安装vagrant

`官网下载地址 https://www.vagrantup.com/downloads.html 选自己的系统版本就行了

安装virtualbox

官网下载地址 https://www.virtualbox.org/wiki/Downloads 选自己的系统版本就行了

下载虚拟机所需要的镜像

这里和平时用的虚拟机镜像不太一样,是box文件 例如CentOS-7-x86_64-Vagrant-1710_01.VirtualBox.box

方式一 :

官网下载地址 https://app.vagrantup.com/boxes/search
下载方式,安装好上面两个东西以后,创建一个目录,创建一个名字为Vagrantfile 的文件,没有后缀的,linux touch出来的那种,可以用gitbash ,touch一个文件, windows 不知道文本文档另存为能不能创建。

1
2
3
Vagrant.configure("2") do |config|
config.vm.box = "centos/7"
end

上面这个centos/7就是你官网打开列表里的名字,
在控制台执行,就会自动从官网下载。

1
$ vagrant up

方法二 :

在这个网站: http://www.vagrantbox.es/

使用方式,在控制台输入

1
2
3
$ vagrant box add {title} {url}
$ vagrant init {title}
$ vagrant up

url 在网站copy就行 title 是你给你的镜像起的别名

方法三:

centos 的官网有vagrant的镜像,提前下载
地址:https://cloud.centos.org/centos/7/vagrant/x86_64/images/
版本比较齐,本博客用的 这个

1
CentOS-7-x86_64-Vagrant-1710_01.VirtualBox.box

下载完成后在你下载的文件目录下执行

1
$ vagrant box add centos7 {你的镜像名}

centos7 是自己起的别名

如果以上都顺利完成那你就成功了一大半了。

创建自己的虚拟机群

新建Vagrant文件

  1. 新建一个目录(英文名,中文名在创建虚拟机的时候会报错,编码错误等,在后续使用最好使用英文的文件夹和文件名),这个是存放虚拟机配置的目录,并进入到这个目录里,创建 Vagrantfile (没有后缀的文件,可以用gitbash,touch/vi 一个),输入

    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
    Vagrant.require_version ">= 1.7.0"

    def set_vbox(vb, config)
    vb.gui = false
    vb.memory = 1024
    vb.cpus = 1
    end

    Vagrant.configure("2") do |config|
    config.vm.provider "virtualbox"
    config.vm.box = "centos7"

    private_count = 11
    (1..6).each do |mid|
    name = (mid ==3) ? "k8s-m" : "k8s-n"
    id = (mid <= 3) ? mid : mid - 3
    config.vm.define "#{name}#{id}" do |n|
    n.vm.hostname = "#{name}#{id}"
    ip_addr = "192.16.35.#{private_count}"
    n.vm.network :private_network, ip: "#{ip_addr}", auto_config: true
    n.vm.provider :virtualbox do |vb, override|
    vb.name = "#{n.vm.hostname}"
    set_vbox(vb, override)
    end
    private_count += 1
    end
    end
    end
  2. vb.gui = false 关闭 虚拟机 gui,vb.memory = 1024 内存1g ,vb.cpus = 1 cpu1核

  3. config.vm.provider “virtualbox” 我们用的是virtualbox,想用其他provider的可以自己试试
  4. config.vm.box = “centos7” 这个名字就是我们自己 增加的 box 的别名
  5. (1..6).each do |mid| 这里只是创建6个,需要多个的可以自己改数字,下面关于hostname的设定,这里是前三个 取名 k8s-m1..3 后面三个取名为 k8s-n1..3 ,只是创建普通虚拟机群的可以自己稍微改动,固定名字

执行vagrant up

在文件目录下执行

1
$ vagrant up

正常情况下应该是直接创建完成,但是总有不测风云。win10 装过docker 的话,开启了hyper-v ,需要关闭,可能会关闭失败

1
2
3
错误Raw-mode is unavailable courtesy of Hyper-V.
(VERR_SUPDRV_NO_RAW_MODE_HYPER_V_ROOT).
返回 代码: E_FAIL (0x80004005)

打开这个官方工具网站,点击下载,并且在cmd 里执行 DG_Readiness_Tool_v3.6.ps1 -Ddisable,注意ps1 的文件名,可能版本不同,不要直接copy 命令,重启就ok,

参考解决方案地址: https://www.jianshu.com/p/2e3429d45aea

连接我们的虚拟机

连接虚拟机 vagrant ssh

1
vagrant ssh k8s-m1

可以从控制台免密码,k8s-m1默认登录的用户是vagrant 密码vagrant,可以手动切换root,但是比较麻烦,点击
《xshell 登陆vagrant》
看我另外一篇博客 《通过xshell 登陆vagrant 》,免密码和用账号密码登陆的介绍。

优雅的关机 vagrant halt

更多的命令网上找有很多,vagrant up 可以唤醒,还有备份等自己决定。

Hello World

发表于 2018-12-01 | 阅读次数:
字数统计: 73 字 | 阅读时长 ≈ 1 分钟

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Quick Start

Create a new post

1
$ hexo new "My New Post"

More info: Writing

Run server

1
$ hexo server

More info: Server

Generate static files

1
$ hexo generate

More info: Generating

Deploy to remote sites

1
$ hexo deploy

More info: Deployment

刘玲弟

刘玲弟

热爱生活

10 日志
5 分类
9 标签
GitHub E-Mail
© Sat Dec 01 2018 08:00:00 GMT+0800 (GMT+08:00) — 2019 刘玲弟 | Site words total count: 9.1k
由 Hexo 强力驱动
|
主题 — NexT.Pisces v5.1.4