总结
在清楚了各个大厂的面试重点之后,就能很好的提高你刷题以及面试准备的效率,接下来小编也为大家准备了最新的互联网大厂资料。
public class InstanceInfoFactory {
//创建服务注册实例对象,EurekaInstanceConfig 是用来加载配置文件中的服务配置信息
public InstanceInfo create(EurekaInstanceConfig config) {
//服务续约Builder设置续约心跳间隔时间和续约超时时间
LeaseInfo.Builder leaseInfoBuilder =
LeaseInfo.Builder.newBuilder() .setRenewalIntervalInSecs(config.getLeaseRenewalIntervalInSeconds())
.setDurationInSecs(config.getLeaseExpirationDurationInSeconds());
//翻译:构建要注册到Eureka服务端的服务实例,绑定相关的配置项目,这里的config就是
// Builder the instance information to be registered with eureka
// server
InstanceInfo.Builder builder = InstanceInfo.Builder.newBuilder();
builder.setNamespace(namespace).setAppName(config.getAppname())
.setInstanceId(config.getInstanceId())
.setAppGroupName(config.getAppGroupName())
.setDataCenterInfo(config.getDataCenterInfo())
.setIPAddr(config.getIpAddress()).setHostName(config.getHostName(false))
.setPort(config.getNonSecurePort())
.enablePort(InstanceInfo.PortType.UNSECURE,
config.isNonSecurePortEnabled())
.setSecurePort(config.getSecurePort())
.enablePort(InstanceInfo.PortType.SECURE, config.getSecurePortEnabled())
.setVIPAddress(config.getVirtualHostName())
.setSecureVIPAddress(config.getSecureVirtualHostName())
.setHomePageUrl(config.getHomePageUrlPath(), config.getHomePageUrl())
.setStatusPageUrl(config.getStatusPageUrlPath(),
config.getStatusPageUrl())
.setHealthCheckUrls(config.getHealthCheckUrlPath(),
config.getHealthCheckUrl(), config.getSecureHealthCheckUrl())
.setASGName(config.getASGName());
…省略…
//添加元数据信息
// Add any user-specific metadata information
for (Map.Entry<String, String> mapEntry : config.getMetadataMap().entrySet()) {
String key = mapEntry.getKey();
String value = mapEntry.getValue();
// only add the metadata if the value is present
if (value != null && !value.isEmpty()) {
builder.add(key, value);
}
}
//构建服务注册实例对象
InstanceInfo instanceInfo = builder.build();
//设置服务租约对象
instanceInfo.setLeaseInfo(leaseInfoBuilder.build());
return instanceInfo;
这里创建了2个对象
-
通过InstanceInfo.Builder 构建 InstanceInfo
-
通过LeaseInfo.Builder 构建LeaseInfo
2.2.com.netflix.appinfo.LeaseInfo
该对象用来描述服务的续约信息
,比如约定的心跳周期,租约有效期,最近一次续约时间等,也是通过InstanceInfoFactory.create
来创建(见上面)源码如下
@JsonRootName(“leaseInfo”)
public class LeaseInfo {
public static final int DEFAULT_LEASE_RENEWAL_INTERVAL = 30;
public static final int DEFAULT_LEASE_DURATION = 90;
// Client settings
//客户端:续约间隔周期时间 30/s 心跳机制
private int renewalIntervalInSecs = DEFAULT_LEASE_RENEWAL_INTERVAL;
//客户端:续约有效时长超过 90s续约失败(服务端会剔除该实例)
private int durationInSecs = DEFAULT_LEASE_DURATION;
// Server populated
//服务端: 服务端设置该租约第一次续约时间
private long registrationTimestamp;
//服务端: 服务端设置该租约最后一次续约时间
private long lastRenewalTimestamp;
//服务端: 服务端设置该租约被剔除时间
private long evictionTimestamp;
//服务端: 服务端设置该服务上线 up 时间
private long serviceUpTimestamp;
这些参数用来维持续约心跳,心跳周期,续约有效期,最近一次续约时间,最后一次续约时间
等
2.3.org.springframework.cloud.client.ServiceInstance
服务发现的抽象接口,约定了服务发现的实例应用有哪些通用的信息,是spring cloud对service discovery的实例信息的抽象接口,该接口可以适配多种注册中心如:Eureka,Zookepper,Consul ,源码如下
/**
-
Represents an instance of a Service in a Discovery System
-
@author Spencer Gibb
*/
public interface ServiceInstance {
/**
服务ID
- @return the service id as registered.
*/
String getServiceId();
/**
服务主机
- @return the hostname of the registered ServiceInstance
*/
String getHost();
/**
服务端口
- @return the port of the registered ServiceInstance
*/
int getPort();
/**
是否开启https
- @return if the port of the registered ServiceInstance is https or not
*/
boolean isSecure();
/**
服务的URI地址
- @return the service uri address
*/
URI getUri();
/**
实例的元数据信息
- @return the key value pair metadata associated with the service instance
*/
Map<String, String> getMetadata();
/**
- @return the scheme of the instance
*/
default String getScheme() {
return null;
}
}
2.4.com.netflix.appinfo.InstanceInfo.InstanceStatus
用来表示服务实例的状态,状态有:UP上线,DOWN下线,STARTING运行中,OUT_OF_SERVICE下线,UNKNOWN未知
@ProvidedBy(EurekaConfigBasedInstanceInfoProvider.class)
@Serializer(“com.netflix.discovery.converters.EntityBodyConverter”)
@XStreamAlias(“instance”)
@JsonRootName(“instance”)
public class InstanceInfo {
…省略…
public enum InstanceStatus {
UP, // Ready to receive traffic
DOWN, // Do not send traffic- healthcheck callback failed
STARTING, // Just about starting- initializations to be done - do not
// send traffic
OUT_OF_SERVICE, // Intentionally shutdown for traffic
UNKNOWN;
public static InstanceStatus toEnum(String s) {
if (s != null) {
try {
return InstanceStatus.valueOf(s.toUpperCase());
} catch (IllegalArgumentException e) {
// ignore and fall through to unknown
logger.debug(“illegal argument supplied to InstanceStatus.valueOf: {}, defaulting to {}”, s, UNKNOWN);
}
}
return UNKNOWN;
}
}
2.5.com.netflix.discovery.shared.Application
Application : 一个Application代表一个应用,里面包含了应用实例列表,即:包含了多个InstanceInfo
实例,源码如下
/**
包含了应用实例列表
-
The application class holds the list of instances for a particular
-
application.
-
@author Karthik Ranganathan
*/
@Serializer(“com.netflix.discovery.converters.EntityBodyConverter”)
@XStreamAlias(“application”)
@JsonRootName(“application”)
public class Application {
private static Random shuffleRandom = new Random();
private String name;
@XStreamOmitField
private volatile boolean isDirty = false;
@XStreamImplicit
private final Set instances;
//无序状态实例列表
private final AtomicReference<List> shuffledInstances;
//map缓存服务ID 对应 实例关系
private final Map<String, InstanceInfo> instancesMap;
…省略…
/**
翻译:添加实例信息
-
Add the given instance info the list.
-
@param i
-
the instance info object to be added.
*/
public void addInstance(InstanceInfo i) {
instancesMap.put(i.getId(), i);
synchronized (instances) {
instances.remove(i);
instances.add(i);
isDirty = true;
}
}
/**
翻译:移出实例信息
-
Remove the given instance info the list.
-
@param i
-
the instance info object to be removed.
*/
public void removeInstance(InstanceInfo i) {
removeInstance(i, true);
}
/**
翻译:获取实例信息列表
-
Gets the list of instances associated with this particular application.
-
-
Note that the instances are always returned with random order after
-
shuffling to avoid traffic to the same instances during startup. The
-
shuffling always happens once after every fetch cycle as specified in
-
{@link EurekaClientConfig#getRegistryFetchIntervalSeconds}.
-
@return the list of shuffled instances associated with this application.
*/
@JsonProperty(“instance”)
public List getInstances() {
return Optional.ofNullable(shuffledInstances.get()).orElseGet(this::getInstancesAsIsFromEureka);
}
/**
通过id获取实例信息
-
Get the instance info that matches the given id.
-
@param id
-
the id for which the instance info needs to be returned.
-
@return the instance info object.
*/
public InstanceInfo getByInstanceId(String id) {
return instancesMap.get(id);
}
…省略…
该类中还提供了一些列方法:
-
void addInstance(InstanceInfo i
添加实例, -
void removeInstance(InstanceInfo i)
移出实例, -
List<InstanceInfo> getInstances()
获取实例列表, -
InstanceInfo getByInstanceId(String id)
通过id获取实例
2.6.com.netflix.discovery.shared.Applications
这个是服务注册列表对象,该类包装了由eureka服务器返回的所有注册表信息,源码如下:
/**
翻译:该类包装了由eureka服务器返回的所有注册表信息
- The class that wraps all the registry information returned by eureka server.
翻译: EurekaClientConfig#getRegistryFetchIntervalSeconds() 方法从 Eureak Server获取服务注册列表,然后对服务进行过滤,
按照(EurekaClientConfig#shouldFilterOnlyUpInstances())的规则过滤上线的服务
-
-
Note that the registry information is fetched from eureka server as specified
-
in {@link EurekaClientConfig#getRegistryFetchIntervalSeconds()}. Once the
-
information is fetched it is shuffled and also filtered for instances with
-
{@link InstanceStatus#UP} status as specified by the configuration
-
{@link EurekaClientConfig#shouldFilterOnlyUpInstances()}.
-
@author Karthik Ranganathan
*/
@Serializer(“com.netflix.discovery.converters.EntityBodyConverter”)
@XStreamAlias(“applications”)
@JsonRootName(“applications”)
public class Applications {
private static class VipIndexSupport {
final AbstractQueue instances = new ConcurrentLinkedQueue<>();
final AtomicLong roundRobinIndex = new AtomicLong(0);
final AtomicReference<List> vipList = new AtomicReference<List>(Collections.emptyList());
public AtomicLong getRoundRobinIndex() {
return roundRobinIndex;
}
public AtomicReference<List> getVipList() {
return vipList;
}
}
private static final String STATUS_DELIMITER = “_”;
private String appsHashCode;
private Long versionDelta;
@XStreamImplicit
//注册成功的服务的集合
private final AbstractQueue applications;
//注册成功的服务的集合,名字和服务对应关系
private final Map<String, Application> appNameApplicationMap;
private final Map<String, VipIndexSupport> virtualHostNameAppMap;
private final Map<String, VipIndexSupport> secureVirtualHostNameAppMap;
/**
创建一个新的空的Eureka应用程序列表。
- Create a new, empty Eureka application list.
*/
public Applications() {
this(null, -1L, Collections.emptyList());
}
/**
这里是把注册成功的服务实例保存起来 registeredApplications是注册成功的实例
-
Note that appsHashCode and versionDelta key names are formatted in a
-
custom/configurable way.
*/
@JsonCreator
public Applications(@JsonProperty(“appsHashCode”) String appsHashCode,
@JsonProperty(“versionDelta”) Long versionDelta,
@JsonProperty(“application”) List registeredApplications) {
this.applications = new ConcurrentLinkedQueue();
this.appNameApplicationMap = new ConcurrentHashMap<String, Application>();
this.virtualHostNameAppMap = new ConcurrentHashMap<String, VipIndexSupport>();
this.secureVirtualHostNameAppMap = new ConcurrentHashMap<String, VipIndexSupport>();
this.appsHashCode = appsHashCode;
this.versionDelta = versionDelta;
//添加到 队列中 applications 和 appNameApplicationMap map中
for (Application app : registeredApplications) {
this.addApplication(app);
}
}
…省略…
/**
添加应用
-
Add the application to the list.
-
@param app
-
the <em>application</em> to be added.
*/
public void addApplication(Application app) {
appNameApplicationMap.put(app.getName().toUpperCase(Locale.ROOT), app);
addInstancesToVIPMaps(app, this.virtualHostNameAppMap, this.secureVirtualHostNameAppMap);
applications.add(app);
}
/**
获取所有注册成功的应用
-
Gets the list of all registered applications from eureka.
-
@return list containing all applications registered with eureka.
*/
@JsonProperty(“application”)
public List getRegisteredApplications() {
return new ArrayList(this.applications);
}
/**
根据名字获取注册成功的应用
-
Gets the list of all registered applications for the given
-
application name.
-
@param appName
-
the application name for which the result need to be fetched.
-
@return the list of registered applications for the given application
-
name.
*/
public Application getRegisteredApplications(String appName) {
return appNameApplicationMap.get(appName.toUpperCase(Locale.ROOT));
}
//总共有多个个实例
public int size() {
return applications.stream().mapToInt(Application::size).sum();
}
//把应用的顺序打乱
public void shuffleInstances(boolean filterUpInstances) {
shuffleInstances(filterUpInstances, false, null, null, null);
}
该类中制定了一些应用操作方法,主要如下
-
public void addApplication(Application app):
添加一个应用 -
public List<Application> getRegisteredApplications():
获取所有注册的应用 -
public Application getRegisteredApplications(String appName):
根据名字获取注册的应用
最后总结我的面试经验
2021年的金三银四一眨眼就到了,对于很多人来说是跳槽的好机会,大厂面试远没有我们想的那么困难,摆好心态,做好准备,你也可以的。
另外,面试中遇到不会的问题不妨尝试讲讲自己的思路,因为有些问题不是考察我们的编程能力,而是逻辑思维表达能力;最后平时要进行自我分析与评价,做好职业规划,不断摸索,提高自己的编程能力和抽象思维能力。
BAT面试经验
实战系列:Spring全家桶+Redis等
其他相关的电子书:源码+调优
面试真题:
pp):`添加一个应用
-
public List<Application> getRegisteredApplications():
获取所有注册的应用 -
public Application getRegisteredApplications(String appName):
根据名字获取注册的应用
最后总结我的面试经验
2021年的金三银四一眨眼就到了,对于很多人来说是跳槽的好机会,大厂面试远没有我们想的那么困难,摆好心态,做好准备,你也可以的。
另外,面试中遇到不会的问题不妨尝试讲讲自己的思路,因为有些问题不是考察我们的编程能力,而是逻辑思维表达能力;最后平时要进行自我分析与评价,做好职业规划,不断摸索,提高自己的编程能力和抽象思维能力。
[外链图片转存中…(img-aSzD5ayB-1715657642502)]
BAT面试经验
实战系列:Spring全家桶+Redis等
[外链图片转存中…(img-UuNox4wq-1715657642502)]
其他相关的电子书:源码+调优
[外链图片转存中…(img-aayyRE6X-1715657642503)]
面试真题:
[外链图片转存中…(img-UoBdJXSA-1715657642503)]
[外链图片转存中…(img-TVBKkR2o-1715657642504)]