技术杂记

本文主要是总结一下最近一个多月学习和折腾的一些技术,归纳了一些知识点,因为有的内容短时间内还无法驾轻就熟甚至还没完全搞明白,所以对这部分内容只做记录,研究将会持续进行。大概有以下几部分,按时间顺序:持续折腾java和python;然后是研究了负载均衡相关的技术;了解k8s和zookeeper;搞了一下jenkins。涉及到一些相关的资料,将在文中贴出来。

java多线程

java多线程,最重要的是要理清以下的几个知识点:

  • 线程安全:保证线程安全,即在多线程并发的情况下,线程的调度不影响任何结果。
  • 同步:同步的作用就是通过人为的调度保证线程的安全,比如使用注解关键字@synchronized。
  • Thread类和Runable接口:实现接口可以避免java类单继承特性带来的局限,增强了程序的健壮性,代码能够被多个线程共享。
  • join方法和yield方法:join方法强制线程执行,yield方法可以让同等级的某一线程先运行。
  • wait方法和sleep方法:wait方法与sleep方法最大的区别在于wait会释放对象锁,而sleep不会。sleep属于Thread类,wait属于Object类。
  • ThreadLocal类:使用ThreadLocal维护变量时,为每一个使用该变量的线程都提供一个变量值的副本,使每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。
  • Lock类和ReentrantLock类:都是锁相关的类,同@synchronized,都是解决同步的问题,处理线程间资源的争端。
  • ReentrantReadWriteLock类:写写,写读互斥;读读不互斥。
  • BlockingQueue:阻塞队列,提供了阻塞接口put和take,带超时功能的阻塞接口offer和poll。
  • ThreadPoolExecutor:用于管理线程,本身不是多线程,了解ThreadPoolExecutor的参数。

资料:
Java中的多线程你只要看这一篇就够了
彻底理解ThreadLocal
并发编程网
BlockingQueue

java nio

与IO面向流不同,其操作以数据块为单位进行,而不是字节。NIO还提供了非阻塞IO,单线程多通道等技术,相关知识点:

  • 同步和异步:同步会不断轮询等待结果,等到了才继续执行后续的操作;异步不会等待,将继续执行其它操作,当有结果返回时再来执行未完成的操作。
  • 阻塞和非阻塞:阻塞就是系统调用在IO调用完成时才返回,被阻塞的进程挂起;非阻塞不管系统调用是否完成都立刻返回。
  • 通道channel:通道类似流,但程序不会直接操作通道,所有的内容先读/写到缓冲区中,然后再从缓冲区取得或者写入。几个比较常用的管道:FileChannel,DatagramChannel,SocketChannel,ServerSocketChannel。
  • Buffer:IO与NIO的操作不同在于,IO操作基于流的形式完成,而NIO的操作需要使用到Buffer。flip方法将Buffer从写切换到读模式,在读模式下,可以读取之前写入到Buffer的数据。Buffer三个属性capacity,position,limit。
  • ServerSocketChannel和DatagramChannel:ServerSocketChannel是可以监听TCP连接的通道, 类似IO中的ServerSocket,常用方法open和accept;DatagramChannel是一个能收发UDP包的通道,类似DatagramSocket,receive和send方法处理数据。
  • Selector:用于非阻塞式网络服务,一个选择器可以被多个通道注册。通道需要configureBlocking为false即非阻塞,然后register注册到选择器。SelectionKey的四个常量:OP_CONNECT,OP_ACCEPT,OP_READ,OP_WRITE。

资料:
高性能IO模型浅析
IO中同步、异步与阻塞、非阻塞的区别
并发编程网
通俗编程——白话NIO之Selector
知乎—怎样理解阻塞非阻塞与同步异步的区别

python相关

看了一些资料,大多是入门相关的:

  • Django:Django的MTV模型,目录结构,urls路由,settings配置,ORM操作,模板渲染等。
  • 猴子补丁:简单来讲,就是不去改变原函数而对其功能进行追加和变更,在此之前需要理解python的函数式编程。
  • setup.py:用来安装模块的。 setup函数里的参数可以指定处理哪些包以及被映射到哪个源码包。了解entry points的使用。

资料:
简约而不简单的Django新手图文教程
Python Monkey patch猴子补丁
关于python中的setup.py

lvs负载均衡技术

lvs即linux虚拟服务器,主要针对一组服务器实现负载均衡调度。有以下实现方式:

  • VS/NAT:调度器收到客户端的报文后,通过NAT转换并结合负载均衡算法,改写报文目的地址,将请求发送到某一台真实服务器上;而真实服务器的响应报文的源地址也会被调度器改写,回应给客户端。

  • VS/TUN:真实服务器和调度器都额外有一块隧道网卡,并将VIP配置到隧道网卡上。客户端的请求报文会首先通过调度器,调度器通过IP隧道封装报文并发送给某一台真实服务器,真实服务器解封装报文后,发现VIP配置到隧道网卡上,所以它的响应报文会直接返回给客户端。

  • VS/DR:类似TUN模式,当调度器接收到客户端的请求时,会改写请求报文的mac地址并转发给真实服务器,真实服务器会将响应报文直接回复给客户端,免去了VS/TUN中的IP隧道开销。但是必须要求调度器与真实服务器都有一块网卡连在同一物理网段。

  • arp_ignore:当客户端向VIP发送请求时,确保该请求发送至Director上的VIP,而不是真实服务器的,需要配置arp_ignore和arp_announce参数。
    arp_ignore为0时,表示无论哪块网卡收到arp查询请求,只要本机有此mac地址的网卡,就给予回应。
    arp_ignore为1时,表示只有请求的mac地址是自己的网卡时,才给予回应。

  • arp_announce:参数说明
    arp_announce为0时,表示无论哪块网卡收到了arp的请求,只要发现本机有请求的mac,就会响应。
    arp_announce为1时,表示尽量避免响应ARP请求中MAC不是本网卡的。如一个主机有多块网卡,其中一块网卡接收到了ARP请求,发现所请求的MAC是本机另一块网卡的,这个时候接收到ARP请求的这块网卡就尽量避免响应。
    arp_announce为2时,表示总是使用最合适的网卡来响应。一个主机有多块网卡,其中一块网卡接收到了ARP请求,发现所请求的MAC是本机另一块网卡的,这个时候接收到ARP请求的这块网卡就一定不响应,只有发现请求的MAC是自己的才给与响应

资料:
Linux负载均衡软件LVS之一
ipvsadm 命令详解
LVS负载均衡中arp_ignore和arp_annonuce参数配置的含义
使用LVS实现负载均衡原理及安装配置详解
LVS-TUN(Virtual Server via IP Tunneling)原理说明与配置用例

mysql调优

mysql的学习,主要是主备以及分区分表:

  • binlog:要保持两台数据库的自动同步,需要开启使用主机上的binlog。binlog日志记录了所有更新了数据或者已经潜在更新了数据,也即是将主机上执行过的sql,在备机上执行一次。
  • 分区分表:分区就是把一张表的数据分成N多个区块,这些区块可以在同一个磁盘上,也可以在不同的磁盘,但它们还是一张表;分表与前者的区别就是把一张表分成若干张小表。

资料:
mysql的binlog详解
mysql分表的3种方法
mysql的分区和分表

k8s和zookeeper学习

  • k8s:Kubernetes是一款docker容器集群的管理系统,类比docker官方的swarm。Kubernetes集群中的两大角色分别为master和minion节点。minion节点是运行docker容器的节点,master节点对外提供一系列管理集群的api接口,实现对集群的管理。还有一款工具etcd,它是一个分布式一致性key-values数据库,用来存储kubernetes的信息。
  • zookeeper:一款分布式一致性协调系统。集群中有两大角色Leader和Learner,Learner角色又分为Observer和Follower。核心是原子广播,这个机制保证了各个Server之间的同步。选主的流程采用fast paxos算法。还有一个著名的分布式一致性算法是raft算法。本文就不做深入阐述了(还在研究中)
  • paxos算法和raft算法

资料:
kubernetes 集群的安装部署
kubernetes 1.3 的安装和集群环境部署
Zookeeper原理架构
Zookeeper系列(一)
Raft 一致性算法
知乎—raft算法与paxos算法相比有什么优势,使用场景有什么差异

jenkins api笔记

最近安排了一个任务,需要写脚本调jenkins的rest api,做了下面两件事:

带参数的rest api:我们在构建Jenkins job时,可以选择带参数的方式,配置任务时指定参数名,然后通过以下api来触发任务

curl -X POST http://user:password@jenkinsurl/job/Robot/buildWithParameters?PKG=pkgname&第2个变量名=第2个变量名的值

服务器免密登陆:bash脚本实现scp免密的功能,需要使用到expect工具

expect -c "
spawn scp -r $PKG $remote_path
expect {
\"*password\" {set timeout 100; send \"$password\r\"}
\"*yes/no\" {send \"yes\r\"; exp_continue;}
}
expect eof"

expect是一种脚本语言,代替人实现与终端的交互。一般spawn后面跟上一条命令操作;expect -c与命令里的expect是不同的,前者是expect工具的使用,后者表示等待输出特定的字符串,然后再进行send操作。单纯的expect脚本还可以接收输入参数:set param0 [lindex $argv 0]

资料:
每次进步一点点——linux expect 使用
shell 中scp密码输入 —expect