-
2016-04-19 19:08:58
今天做实验时遇到了这样的问题:
ArgumentNullException: 值不能为 null。
问题的错误提示如下:
行 14: { 行 15: string categoryId = Request.QueryString["CategoryId"]; 行 16: var category = (from c in db.Category 行 17: where c.CategoryId == int.Parse(categoryId) 行 18: select c).First();
源文件: e:\mywebs\Expelement\WebSet\Updata.aspx.cs 行: 16
堆栈跟踪:
后来发现要 对传的值进行是否为空值判断,改成以下就行了[ArgumentNullException: 值不能为 null。 参数名: String] System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal) +10725658 System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info) +145 System.Int32.Parse(String s) +23 lambda_method(Closure ) +101 [TargetInvocationException: 调用的目标发生了异常。] System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor) +0 System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments) +192 System.Delegate.DynamicInvokeImpl(Object[] args) +117 System.Data.Linq.CommonDataServices.GetKeyFromPredicate(MetaType type, Dictionary`2 keys, Expression mex, Expression vex) +459 System.Data.Linq.CommonDataServices.GetKeysFromPredicate(MetaType type, Dictionary`2 keys, Expression expr) +257 System.Data.Linq.CommonDataServices.GetKeyValues(MetaType type, LambdaExpression predicate) +87 System.Data.Linq.CommonDataServices.GetCachedObject(Expression query) +573 System.Data.Linq.CommonDataServices.GetCachedObject(Expression query) +308 System.Data.Linq.SqlClient.SqlProvider.GetCachedResult(Expression query) +44 System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute(Expression query) +91 System.Data.Linq.DataQuery`1.System.Linq.IQueryProvider.Execute(Expression expression) +58 System.Linq.Queryable.First(IQueryable`1 source) +251 Updata.Page_Load(Object sender, EventArgs e) in e:\mywebs\Expelement\WebSet\Updata.aspx.cs:16 System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +51 System.Web.UI.Control.OnLoad(EventArgs e) +92 System.Web.UI.Control.LoadRecursive() +54 System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +772
if (!String.IsNullOrEmpty(Request.QueryString["CategoryId"])) {
string categoryId = Request.QueryString["CategoryId"];
var category = (from c in db.Category
where c.CategoryId == int.Parse(categoryId)
select c).First();
我也是个菜鸟,希望对你有用吧
更多相关内容 -
Spark开发注意: collect_list、collect_set会去除Null值
2021-11-10 08:22:44今天我们踩到一个collect_list的坑,collect_list的结果不包含null值 name city 张三 广州 null 广州 李四 深圳 对city作group by后collect_list(name)得到的结果中city='广州’为List(‘张三’),...今天我们踩到一个collect_list的坑,collect_list的结果不包含null值
name city 张三 广州 null 广州 李四 深圳 对city作group by后collect_list(name)得到的结果中city='广州’为List(‘张三’),没有null值。跟踪源码:
def collect_list(e: Column): Column = withAggregateFunction { CollectList(e.expr) }
collect_list使用CollectList计算
@ExpressionDescription( usage = "_FUNC_(expr) - Collects and returns a list of non-unique elements.") case class CollectList( child: Expression, mutableAggBufferOffset: Int = 0, inputAggBufferOffset: Int = 0) extends Collect[mutable.ArrayBuffer[Any]] { def this(child: Expression) = this(child, 0, 0) override lazy val bufferElementType = child.dataType override def convertToBufferElement(value: Any): Any = InternalRow.copyValue(value) override def withNewMutableAggBufferOffset(newMutableAggBufferOffset: Int): ImperativeAggregate = copy(mutableAggBufferOffset = newMutableAggBufferOffset) override def withNewInputAggBufferOffset(newInputAggBufferOffset: Int): ImperativeAggregate = copy(inputAggBufferOffset = newInputAggBufferOffset) override def createAggregationBuffer(): mutable.ArrayBuffer[Any] = mutable.ArrayBuffer.empty override def prettyName: String = "collect_list" override def eval(buffer: mutable.ArrayBuffer[Any]): Any = { new GenericArrayData(buffer.toArray) } }
CollectList继承于Collect[mutable.ArrayBuffer[Any]]
/** * A base class for collect_list and collect_set aggregate functions. * * We have to store all the collected elements in memory, and so notice that too many elements * can cause GC paused and eventually OutOfMemory Errors. */ abstract class Collect[T <: Growable[Any] with Iterable[Any]] extends TypedImperativeAggregate[T] { val child: Expression override def children: Seq[Expression] = child :: Nil override def nullable: Boolean = true override def dataType: DataType = ArrayType(child.dataType) // Both `CollectList` and `CollectSet` are non-deterministic since their results depend on the // actual order of input rows. override lazy val deterministic: Boolean = false override def defaultResult: Option[Literal] = Option(Literal.create(Array(), dataType)) protected def convertToBufferElement(value: Any): Any override def update(buffer: T, input: InternalRow): T = { val value = child.eval(input) // Do not allow null values. We follow the semantics of Hive's collect_list/collect_set here. // See: org.apache.hadoop.hive.ql.udf.generic.GenericUDAFMkCollectionEvaluator if (value != null) { buffer += convertToBufferElement(value) } buffer } override def merge(buffer: T, other: T): T = { buffer ++= other } protected val bufferElementType: DataType private lazy val projection = UnsafeProjection.create( Array[DataType](ArrayType(elementType = bufferElementType, containsNull = false))) private lazy val row = new UnsafeRow(1) override def serialize(obj: T): Array[Byte] = { val array = new GenericArrayData(obj.toArray) projection.apply(InternalRow.apply(array)).getBytes() } override def deserialize(bytes: Array[Byte]): T = { val buffer = createAggregationBuffer() row.pointTo(bytes, bytes.length) row.getArray(0).foreach(bufferElementType, (_, x: Any) => buffer += x) buffer } }
在update方法中可以看到判空的逻辑,注释内容说要与Hive的collect_list/collect_set方法保持一致。
如果collect_list再支持一个可选参数,用于控制是否过滤null就好了,于是我们自定义了collect_list函数object CollectListWithNullUDAF extends UserDefinedAggregateFunction { // Data types of input arguments of this aggregate function override def inputSchema: StructType = StructType(StructField("element", StringType) :: Nil) // Data types of values in the aggregation buffer override def bufferSchema: StructType = StructType(StructField("buffer", ArrayType(StringType, containsNull = true)) :: Nil) // The data type of the returned value override def dataType: DataType = ArrayType(StringType, containsNull = true) // Whether this function always returns the same output on the identical input override def deterministic: Boolean = true // Initializes the given aggregation buffer. The buffer itself is a `Row` that in addition to // standard methods like retrieving a value at an index (e.g., get(), getBoolean()), provides // the opportunity to update its values. Note that arrays and maps inside the buffer are still // immutable. override def initialize(buffer: MutableAggregationBuffer): Unit = { buffer(0) = List.empty[String] } // Updates the given aggregation buffer `buffer` with new input data from `input` override def update(buffer: MutableAggregationBuffer, input: Row): Unit = { implicit val defaultFormats: DefaultFormats.type = org.json4s.DefaultFormats var list = buffer.get(0).asInstanceOf[mutable.WrappedArray[String]].toList val value = input.get(0) if (value == null) { list = list.+:(null) } else { list = list.+:(value.toString) } buffer(0) = list } // Merges two aggregation buffers and stores the updated buffer values back to `buffer1` override def merge(buffer1: MutableAggregationBuffer, buffer2: Row): Unit = { val listResult = buffer1.get(0).asInstanceOf[mutable.WrappedArray[String]].toList val listTemp = buffer2.get(0).asInstanceOf[mutable.WrappedArray[String]].toList buffer1(0) = listResult ++ listTemp } // Calculates the final result override def evaluate(buffer: Row): List[String] = { val list = buffer.get(0).asInstanceOf[mutable.WrappedArray[String]].reverse.toList list } } // 方法注册 spark.udf.register("collect_list_with_null", CollectListWithNullUDAF)
-
C# Socket BeginReceive方法中参数byte[] buffer 的理解
2019-04-09 22:50:26TcpClient tcpClient; byte[] byteBuffer= new byte[1024*4];...tcpClient.Client.BeginReceive(byteBuffer, 0, byteBuffer.Length, SocketFlags.None, ReceiveCallBack, null); // 参数: // buffer:...TcpClient tcpClient;
byte[] byteBuffer= new byte[1024*4];
tcpClient.Client.BeginReceive(byteBuffer, 0, byteBuffer.Length, SocketFlags.None, ReceiveCallBack, null);
// 参数:
// buffer:
// 类型的数组 System.Byte ,它是接收到的数据的存储位置。如上代码片段所示:当发送端以10ms的间隔频率密集发送数据时,接收方利用Thread.Sleep(10000) 刻意等待10s 后观察测试结果:
发送方发了382次,此时接收方数据先写入socket系统缓冲区累加了,但我们程序读取延时,所以只用了6次就全部读取完了。
如果把上面伪代码的 byteBuffer 设置为发送数据长度(测试发送的数据长度为48:)的一半:即 byte[] byteBuffer=new byte[24];
再次测试发现接收次数为发送次数的两倍,这个好理解:接收容量小了一半,次数就要增加一倍,此时和是否有Sleep无关。Sleep等待只是使得接收数据变慢了。
由上可知:这个buffer参数 太小,则接收太慢,如果参数过大,则可以最大化利用网络I/O性能,但相应速度可能下降,通常要保持一个合理的值,如1024*2 或1024*4 等;
附加一个Socket异步接收模型:参考了这个Blog 的封装,但实际测试有些bug,做了些改进:
比如连接时,不小心触发了多次连接就可能报异常:
System.InvalidOperationException:“同一个套接字上正在进行另一个异步操作时,不能调用 BeginConnect
另外测试发现一个比较严重的bug,如果客户端Socket异步发送频繁:比如:
for(int i=0;i<(int)this.numericUpDown1.Value;i++) { PipeReader l100 = new PipeReader { PipeCode ="#"+ (i + 1).ToString("0000"), ProductType= ProductType.S45, IsNormalCode=true }; client.SendAsync(l100.ToBytes()); }
此Socket异步模型会导致数据漏收,比如发了50个,实际只收到了2,3个,问题发生的原因在线程同步锁ManualResetEvent的使用导致,去掉这个锁的逻辑,可以接受完整;或者在客户端发送消息时加上延时,则也可接收完整的回调;
//友情提示:下面的封装异步Tcp客户端,可以拿来做测试用,如果实际项目利用需要谨慎使用 public class AsynSocketClient { #region private /// <summary> /// 用于控制异步接收消息 /// </summary> // private ManualResetEvent doReceive = new ManualResetEvent(false); private TcpClient tcpClient; //标识客户端是否接收数据 private bool isStopWork = false; #endregion /// <summary> /// 是否释放对象了 /// </summary> public bool IsClosed { get => isStopWork; set => isStopWork = value; } #region 事件 /// <summary> /// 客户端连接完成、发送完成、连接异常或者服务端关闭触发的事件 /// </summary> public event Action<TcpClient, SocketAction> Completed; /// <summary> /// 客户端接收消息触发的事件 /// </summary> public event EventHandler<DataEventArgs> Received; #endregion public AsynSocketClient() { tcpClient = new TcpClient(); } #region 连接 /// <summary> /// 异步连接 /// </summary> /// <param name="ip">要连接的服务器的ip地址</param> /// <param name="port">要连接的服务器的端口</param> public void ConnectAsync(string ip, int port) { IPAddress ipAddress = null; try { ipAddress = IPAddress.Parse(ip); } catch (Exception) { throw new Exception("ip地址格式不正确,请使用正确的ip地址!"); } try { if (!tcpClient.Connected) { tcpClient.BeginConnect(ipAddress, port, ConnectCallBack, tcpClient); } else if (isStopWork) { isStopWork = false; OnComplete(tcpClient, SocketAction.Connect); } } catch { } } /// <summary> /// 异步连接的回调函数 /// </summary> /// <param name="ar"></param> private void ConnectCallBack(IAsyncResult ar) { try { TcpClient client = ar.AsyncState as TcpClient; client.EndConnect(ar); OnComplete(client, SocketAction.Connect); } catch { } } #endregion #region 收发数据 /// <summary> /// 异步接收消息 /// </summary> private void ReceiveAsync() { // doReceive.Reset(); StateObject obj = new StateObject(); obj.TcpClient = tcpClient; tcpClient.Client.BeginReceive(obj.ListData, 0, obj.ListData.Length, SocketFlags.None, ReceiveCallBack, obj); // doReceive.WaitOne(); } /// <summary> /// 异步发送消息 /// </summary> /// <param name="msg"></param> public void SendAsync(string msg) { byte[] listData = Encoding.UTF8.GetBytes(msg); SendAsync(listData); } public void SendAsync(byte[] bytes) { try { if (tcpClient.Client == null) { throw new Exception("连接已经断开"); } if (isStopWork) { return; } tcpClient.Client.BeginSend(bytes, 0, bytes.Length, SocketFlags.None, SendCallBack, tcpClient); } catch (SocketException ex) { if (ex.ErrorCode == (int)SocketError.ConnectionAborted) { throw new Exception("连接已经断开"); } } } private void ReceiveCallBack(IAsyncResult ar) { StateObject state = ar.AsyncState as StateObject; int count = -1; try { if (isStopWork) { return; } count = state.TcpClient.Client.EndReceive(ar); //doReceive.Set(); } catch (Exception ex) { //如果发生异常,说明客户端失去连接,触发关闭事件 Stop(); OnComplete(state.TcpClient, SocketAction.Close); } if (count > 0) { Received?.Invoke(this, new DataEventArgs() { Data = state.ListData.Take<byte>(count).ToArray() }); } } private void SendCallBack(IAsyncResult ar) { TcpClient client = ar.AsyncState as TcpClient; try { client.Client.EndSend(ar); OnComplete(client, SocketAction.SendMsg); } catch (Exception) { //如果发生异常,说明客户端失去连接,触发关闭事件 Stop(); OnComplete(client, SocketAction.Close); } } #endregion public virtual void OnComplete(TcpClient client, SocketAction action) { if (Completed != null) Completed(client, action); if (action == SocketAction.Connect) { // 接收数据 ThreadPool.QueueUserWorkItem(x => { while (!isStopWork) { try { ReceiveAsync(); Thread.Sleep(20); } catch (Exception) { Stop(); OnComplete(client, SocketAction.Close); } } }); } else if (action == SocketAction.Close) { try { Thread.Sleep(50); this.Received = null; tcpClient.Close(); } catch { } } } void Stop() { isStopWork = true; } public void Close() { if (tcpClient != null) { try { Stop(); IsClosed = true; Completed = null; Received = null; tcpClient.GetStream().Close(); } catch(Exception ex) { } } } } /// <summary> /// 接收socket的行为 /// </summary> public enum SocketAction { /// <summary> /// socket发生连接 /// </summary> Connect = 1, /// <summary> /// socket发送数据 /// </summary> SendMsg = 2, /// <summary> /// socket关闭 /// </summary> Close = 4 } public class StateObject { public TcpClient TcpClient { get; set; } private byte[] listData = new byte[1024*4]; /// <summary> /// 接收的数据 /// </summary> public byte[] ListData { get { return listData; } set { listData = value; } } } public class DataEventArgs : EventArgs { public byte[] Data { get; set; } public int Offset { get; set; } public int Length { get; set; } }
-
Geometry 使用 buffer 方法 生成缓冲区,如何限定传入的diatance的单位为米?
2019-03-13 13:50:58这个 buffer方法,是传入一个double类型的diatance,找不到相关api,不知道这个值的单位,求问如果以米为单位怎么设定?是不是和这个方法的两个重载方法有关 buffer(distance, quadrantSegments)和buffer(distance,... -
解决fegin+hystrix中RequestContextHolder.getRequestAttributes();返回null值的解决方法
2019-07-27 15:38:51* @description: 自定义隔离策略 解决RequestContextHolder.getRequestAttributes()问题 为null * @author: wm_yu * @create: 2019/07/26 **/ @Component @Primary @Slf4j public class ...转载大佬的文章: http://www.itmuch.com/spring-cloud-sum/hystrix-threadlocal/
自定义feign拦截器
package com.wm.commonfeign.config; import feign.RequestInterceptor; import feign.RequestTemplate; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Configuration; import org.springframework.util.ObjectUtils; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import java.util.Enumeration; import java.util.LinkedHashMap; import java.util.Map; /** * @class_name: CustomFeignConfig * @description: 服务间调用携带authorization请求头,拦截器统一处理 * @author: wm_yu * @create: 2019/07/26 **/ @Configuration @Slf4j public class CustomFeignConfig implements RequestInterceptor { private static final String TOKEN_HEADER = "authorization"; @Override public void apply(RequestTemplate requestTemplate) { HttpServletRequest request = getHttpServletRequest(); //获取请求参数 TODO 获取请求参数失败 RequestInterceptor是在请求前给request添加参数,实际上参数并没有同步过来,待解决,建议使用feign官方的输出日志 String jsonString = this.getRequestJsonString(request); //输出调用feign日志 log.info("feign调用请求方法日志打印,methodName={},Parameter={}",request.getMethod(),jsonString); if (ObjectUtils.isEmpty(request)) { requestTemplate.header(TOKEN_HEADER, getHeaders(request).get(TOKEN_HEADER)); } } /** * 获取请求的request * @return */ private HttpServletRequest getHttpServletRequest() { try { // hystrix隔离策略会导致RequestContextHolder.getRequestAttributes()返回null // 解决方案:http://www.itmuch.com/spring-cloud-sum/hystrix-threadlocal/ ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); if (!ObjectUtils.isEmpty(attributes)){ return attributes.getRequest(); } return null; } catch (Exception e) { log.error("feign拦截器中获取HttpServletRequest error...",e.getMessage(),e); return null; } } /** * 获取所有的header中的参数 * @param request * @return */ private Map<String, String> getHeaders(HttpServletRequest request) { Map<String, String> map = new LinkedHashMap<>(); Enumeration<String> enumeration = request.getHeaderNames(); while (enumeration.hasMoreElements()) { String key = enumeration.nextElement(); String value = request.getHeader(key); map.put(key, value); } return map; } /** * 获取request中的json数据 * @param request * @return */ public String getRequestJsonString(HttpServletRequest request){ try { int contentLength = request.getContentLength(); if (contentLength < 0) { return null; } byte buffer[] = new byte[contentLength]; for (int i = 0; i < contentLength;) { int readlen = request.getInputStream().read(buffer, i, contentLength - i); if (readlen == -1) { break; } i += readlen; } String charEncoding = request.getCharacterEncoding(); if (charEncoding == null) { charEncoding = "UTF-8"; } return new String(buffer, charEncoding); } catch (Exception e) { log.error("解析request中的流异常....",e.getMessage(),e); } return null; } }
途中代码处返回null
解决方法:自定义熔断策略
package com.wm.commonfeign.strategy; import com.netflix.hystrix.HystrixThreadPoolKey; import com.netflix.hystrix.HystrixThreadPoolProperties; import com.netflix.hystrix.strategy.HystrixPlugins; import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy; import com.netflix.hystrix.strategy.concurrency.HystrixRequestVariable; import com.netflix.hystrix.strategy.concurrency.HystrixRequestVariableLifecycle; import com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifier; import com.netflix.hystrix.strategy.executionhook.HystrixCommandExecutionHook; import com.netflix.hystrix.strategy.metrics.HystrixMetricsPublisher; import com.netflix.hystrix.strategy.properties.HystrixPropertiesStrategy; import com.netflix.hystrix.strategy.properties.HystrixProperty; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; import java.util.concurrent.BlockingQueue; import java.util.concurrent.Callable; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; /** * @class_name: CustomFeignHystrixConcurrencyStrategy * @description: 自定义隔离策略 解决RequestContextHolder.getRequestAttributes()问题 为null * @author: wm_yu * @create: 2019/07/26 **/ @Component @Primary @Slf4j public class CustomFeignHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy{ private HystrixConcurrencyStrategy hystrixConcurrencyStrategy; public CustomFeignHystrixConcurrencyStrategy() { try { this.hystrixConcurrencyStrategy = HystrixPlugins.getInstance().getConcurrencyStrategy(); if (this.hystrixConcurrencyStrategy instanceof CustomFeignHystrixConcurrencyStrategy) { // Welcome to singleton hell... return; } HystrixCommandExecutionHook commandExecutionHook = HystrixPlugins.getInstance().getCommandExecutionHook(); HystrixEventNotifier eventNotifier = HystrixPlugins.getInstance().getEventNotifier(); HystrixMetricsPublisher metricsPublisher = HystrixPlugins.getInstance().getMetricsPublisher(); HystrixPropertiesStrategy propertiesStrategy = HystrixPlugins.getInstance().getPropertiesStrategy(); this.logCurrentStateOfHystrixPlugins(eventNotifier, metricsPublisher, propertiesStrategy); HystrixPlugins.reset(); HystrixPlugins.getInstance().registerConcurrencyStrategy(this); HystrixPlugins.getInstance().registerCommandExecutionHook(commandExecutionHook); HystrixPlugins.getInstance().registerEventNotifier(eventNotifier); HystrixPlugins.getInstance().registerMetricsPublisher(metricsPublisher); HystrixPlugins.getInstance().registerPropertiesStrategy(propertiesStrategy); } catch (Exception e) { log.error("Failed to register Sleuth Hystrix Concurrency Strategy", e); } } private void logCurrentStateOfHystrixPlugins(HystrixEventNotifier eventNotifier, HystrixMetricsPublisher metricsPublisher, HystrixPropertiesStrategy propertiesStrategy) { if (log.isDebugEnabled()) { log.debug("Current Hystrix plugins configuration is [" + "concurrencyStrategy [" + this.hystrixConcurrencyStrategy + "]," + "eventNotifier [" + eventNotifier + "]," + "metricPublisher [" + metricsPublisher + "]," + "propertiesStrategy [" + propertiesStrategy + "]," + "]"); log.debug("Registering Sleuth Hystrix Concurrency Strategy."); } } @Override public <T> Callable<T> wrapCallable(Callable<T> callable) { RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); return new WrappedCallable<>(callable, requestAttributes); } @Override public ThreadPoolExecutor getThreadPool(HystrixThreadPoolKey threadPoolKey, HystrixProperty<Integer> corePoolSize, HystrixProperty<Integer> maximumPoolSize, HystrixProperty<Integer> keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) { return this.hystrixConcurrencyStrategy.getThreadPool(threadPoolKey, corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue); } @Override public ThreadPoolExecutor getThreadPool(HystrixThreadPoolKey threadPoolKey, HystrixThreadPoolProperties threadPoolProperties) { return this.hystrixConcurrencyStrategy.getThreadPool(threadPoolKey, threadPoolProperties); } @Override public BlockingQueue<Runnable> getBlockingQueue(int maxQueueSize) { return this.hystrixConcurrencyStrategy.getBlockingQueue(maxQueueSize); } @Override public <T> HystrixRequestVariable<T> getRequestVariable(HystrixRequestVariableLifecycle<T> rv) { return this.hystrixConcurrencyStrategy.getRequestVariable(rv); } static class WrappedCallable<T> implements Callable<T> { private final Callable<T> target; private final RequestAttributes requestAttributes; public WrappedCallable(Callable<T> target, RequestAttributes requestAttributes) { this.target = target; this.requestAttributes = requestAttributes; } @Override public T call() throws Exception { try { RequestContextHolder.setRequestAttributes(requestAttributes); return target.call(); } finally { RequestContextHolder.resetRequestAttributes(); } } } }
配置fegin支持hystrix,并指定熔断的超时
feign: hystrix: enabled: true # hystrix配置 hystrix: shareSecurityContext: true command: default: execution: isolation: thread: timeoutInMilliseconds: 60000
feign提供给其他服务调用
package com.wm.examapi.feign; import com.wm.commoncore.constant.ServiceConstant; import com.wm.commoncore.model.Response; import com.wm.commonfeign.config.CustomFeignConfig; import com.wm.examapi.feign.fallback.ExaminationServiceClientFallbackImpl; import com.wm.examapi.model.Examination; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; /** * @class_name: ExaminationServiceClient * @description: 考试接口 .... FeignClient需要指定configuration为CustomFeignConfig,用于服务间调用携带token * @author: wm_yu * @create: 2019/07/26 **/ @FeignClient(name = ServiceConstant.EXAM_SERVICE, configuration = CustomFeignConfig.class, fallback = ExaminationServiceClientFallbackImpl.class) public interface ExaminationServiceClient { /** * 查询考试数量 * * @param examination 租户标识 * @return ResponseBean */ /** * 注意这里只能用RequestMapping指定请求方法为post,不能使用@PostMapping * @param examination * @return */ @RequestMapping(method = RequestMethod.POST,value = "/api/exam/getExaminationCount") Response<Integer> findExaminationCount(@RequestBody Examination examination); }
配置熔断类:
package com.wm.examapi.feign.fallback; import com.wm.commoncore.constant.BussiConstant; import com.wm.commoncore.model.Response; import com.wm.examapi.feign.ExaminationServiceClient; import com.wm.examapi.model.Examination; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.RequestBody; /** * @class_name: ExaminationServiceClientFallbackImpl * @description: 考试服务熔断 * @author: wm_yu * @create: 2019/07/26 **/ @Slf4j @Component public class ExaminationServiceClientFallbackImpl implements ExaminationServiceClient { private Throwable throwable; @Override public Response<Integer> findExaminationCount(@RequestBody Examination examination) { log.error("调用{}异常, {}, {}", "findExaminationCount", examination.getTenantCode(),throwable); return Response.createError(BussiConstant.EXAM_SERVICE_FEIGN_ERROR,0); } public Throwable getThrowable() { return throwable; } public void setThrowable(Throwable throwable) { this.throwable = throwable; } }
创建熔断工厂,生成熔断实例package com.wm.examapi.feign.factory; import com.wm.examapi.feign.ExaminationServiceClient; import com.wm.examapi.feign.fallback.ExaminationServiceClientFallbackImpl; import feign.hystrix.FallbackFactory; import org.springframework.stereotype.Component; /** * @class_name: UserServiceClientFallbackFactory * @description: 考试系统熔断器工厂 * @author: wm_yu * @create: 2019/07/26 **/ @Component public class ExaminationServiceClientFallbackFactory implements FallbackFactory<ExaminationServiceClient> { @Override public ExaminationServiceClient create(Throwable throwable) { ExaminationServiceClientFallbackImpl examinationServiceClientFallback = new ExaminationServiceClientFallbackImpl(); examinationServiceClientFallback.setThrowable(throwable); return examinationServiceClientFallback; } }
启动类扫描feign包
package com.wm.userservice; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; @SpringBootApplication @EnableDiscoveryClient //注册中心发现 @MapperScan("com.wm.userservice.mapper") @EnableFeignClients(basePackages = {"com.wm.examapi.feign"}) //扫描fegin包 @ComponentScan({"com.wm.examapi.feign","com.wm.userservice","com.wm.commonfeign"}) //主要是需要扫描到内部的包(内部不同模块),如:fegin配置等 public class UserServiceApplication { public static void main(String[] args) { SpringApplication.run(UserServiceApplication.class, args); } /** * 跨域过滤器 * @return */ @Bean public CorsFilter corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", buildConfig()); return new CorsFilter(source); } private CorsConfiguration buildConfig() { CorsConfiguration corsConfiguration = new CorsConfiguration(); corsConfiguration.addAllowedOrigin("*"); corsConfiguration.addAllowedHeader("*"); corsConfiguration.addAllowedMethod("*"); return corsConfiguration; } }
这里多配置一个vue跨域解决的
本来是想在拦截器中输出日志信息,发现不行,这个待处理,目前个人理解的原因的:
后面采用官方的feign日志输出:
很简单:
创建一个日志配置类:
如下:
package com.wm.commonfeign.config; import feign.Logger; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * @class_name: FeignLogConfig * @description: 配置feign日志输出 * @author: wm_yu * @create: 2019/07/27 **/ /** * Feign logging * A logger is created for each Feign client created. By default the name of the logger is the full class name of the interface used to create the Feign client. Feign logging only responds to the DEBUG level. * * application.yml * * logging.level.project.user.UserClient: DEBUG * * * The Logger.Level object that you may configure per client, tells Feign how much to log. Choices are: * * 可以为每个客户端配置日志级别(Logger.Level),选项有: * * NONE, No logging (DEFAULT). * BASIC, Log only the request method and URL and the response status code and execution time. * HEADERS, Log the basic information along with request and response headers. * FULL, Log the headers, body, and metadata for both requests and responses. * For example, the following would set the Logger.Level to FULL: * * 下例将日志级别设为全部(FULL): * * @Configuration * public class FooConfiguration { * @Bean * Logger.Level feignLoggerLevel() { * return Logger.Level.FULL; * } * } */ @Configuration public class FeignLogConfig { @Bean Logger.Level feignLoggerLevel() { return Logger.Level.FULL; } }
注释掉的为官方文档中的解释
在yml中配置需要输出的日志级别和指明feign类
logging: level: root: info ####sql日志 com.wm.examservice.mapper: debug #### feign日志 com.wm.examapi.feign: debug
-
AndroidQ 图形系统(4)queueBuffer函数分析
2020-06-10 22:04:14上一篇文章分析了dequeueBuffer函数的过程,本篇接着分析queueBuffer函数,当我们需要绘制图像时,调用dequeueBuffer函数获取到可用的GraphicBuffer之后就可以开始绘制了,最常见的绘制操作就是Android上层View的... -
Unity CommandBuffer或是Camera重定向RenderTarget的ColorBuffer & DepthBuffer
2020-03-19 19:08:32关键API:_Camera.SetTargetBuffers(colorRT.colorBuffer, depthRT.depthBuffer);或CommandBuffer.SetRenderTarget(RenderTargetIdentifier[] colors, RenderTargetIdentifier depth); 下面我用到的是Camera的API ... -
Netty源码分析-Netty4缓冲区Buffer性能优化之Pooled池化机制
2019-01-01 17:45:23在对象引用的实现中,每当一个Buffer实例没有被引用时,则会销毁该对象实例,如被GC回收,但是Buffer对象创建时的内存分配开销是比较大的,如果频繁创建Buffer对象,频繁进行内存分配释放,则开销较大,影响性能,故... -
推荐mysql内存参数设置值
2018-07-30 16:04:09主要用来存放每一个线程自身的标识信息,如线程id,线程运行时基本信息等等,我们可以通过 thread_stack 参数来设置为每一个线程栈分配多大的内存。 Global,No Dynamic,Default 192K(32bit), 256K(32bit), 推荐配置... -
【SpringCloud】Gateway 配置全局过滤器获取请求参数和响应值
2020-07-02 20:51:18【SpringCloud】Gateway 配置全局过滤器获取请求参数和响应值 实现Ordered接口getOrder()方法,数值越小越靠前执行,记得这一点就OK了。 获取请求参数RequestBody @Component @Slf4j @AllArgsConstructor public ... -
Ring Buffer介绍
2019-09-09 16:29:14一般来说,对于多线程共享数据,需要使用mutex来同步,这样共享数据才不至于发生不可预测的修改/读取,然而,mutex的使用也带来了额外的系统开销,ring buffer/queue 的引入,就是为了有效地解... -
对于过滤器中使用getInputStream()、getParameter()接收参数接收不到的一些知识,以及解决方法。
2018-02-06 16:24:19昨天,我需要做一个从主项目分离出来的项目对主项目的功能的调用,但是在写Http发送Post请求时,遇到了主项目接收不到参数的情况,从而引起了我对项目接收参数的一些探讨。 我们知道,对于spring项目接收参数用的... -
为什么阿里巴巴不建议MySQL使用Text类型?
2020-11-09 09:24:29好家伙,你不说我真不知道,直接好家伙 -
关于空指针(指针指向为NULL)和void类型的指针的理解
2018-07-16 11:25:58正在学C,书上老说空指针,或者说void指针,对于我这样的... 不经发问,什么叫指向为空呢?要理解这点,必须理解如下几点(有点啰嗦,但很细,别嫌我烦):(a)任何指针都有类型(说穿了指针都是变量,只不过变... -
C#数据结构-Array.Copy和Buffer.BlockCopy详解
2018-03-28 16:53:30通过对C#文档中Array.Copy()和Buffer.BlockCopy()两个方法的整理,深刻理解其运行原理及实现方式。在理解了Array.Copy()之后,从而对List<T>的拷贝、插入、删除操作实现,有一个更深入的理解。 一、Array.... -
Linux buffer/cache 内存占用过高的原因以及解决办法
2020-03-02 20:59:22这个值默认值一般为 100 。 另外也可以使用 slabtop 分析内存使用情况。一般情况下, dentry 和 *_inode_cache 值越高回收的效果越好。 为什么是 dentry 和 *_inode_cache 呢,这是因为当读写文件时内核会为该... -
MYSQL INNODB_SORT_BUFFER_SIZE 和 SORT BUFFER SIZE 有什么不同如何调整优化
2020-10-21 06:00:00MYSQL 上的配置参数中带有 innodb_sort_buffer_size ,Sort_buffer_size 两个参数的意义有什么不同. Sort_buffer_size 针对的是每一个SESSION连接,他并不是仅仅服务于INNODB数据库引擎的,他是对于数据提取后的一种... -
Java微信开发——生成带参数的二维码以及扫描带参数二维码事件
2018-04-25 17:04:06临时二维码主要用于帐号绑定等不要求二维码永久保存的业务场景2、永久二维码,是无过期时间的,但数量较少(目前为最多10万个)。永久二维码主要用于适用于帐号绑定、用户来源统计等场景。用户扫描带场景值二维码时... -
5.2 应用程序和驱动程序中buffer的传输流程
2016-08-23 20:48:03摄像头采集的数据,是通过buffer的形式传到驱动程序中,然后驱动程序使能CSI设备来采集数据。之后将采集到的数据再次通过buffer的形式传递给应用程序中。这个过程中使用了VIDIOC_REQBUFS,VIDIOC_QUERYBUF,VIDIOC_... -
Kafka配置参数详解
2018-12-11 10:39:11Kafka主要参数详解 一、相关参数配置 ############################ System ############################# ...#监听地址,不设为所有地址 host.name=debugo01 # 处理网络请求的最... -
SpringBoot拦截器或过滤器中使用流读取参数后,controller中注解读取不到参数
2017-11-02 10:13:47有个需求就是要加一个拦截器和过滤器,在拦截器中我需要获取到前端传过来的json数据,按照常理来说,获取请求参数使用request.getParameter()方法就可以,但是不知道为什么在这个项目里面获取不到。这时候我想到了... -
Unity 的CommandBuffer基础
2019-03-25 15:09:35CommandBuffer,上 官方文档。...如下图,我们可以根据参数指定CommandBuffer在绿色的点上添加执行命令。 Command buffers也可以结合屏幕后期效果使用。 那CommandBuffer是个什么鬼,先来实现一个最简... -
JAVA -- BufferdInputStream.mark(int readlimit)参数设置不生效
2022-03-06 12:59:20} else if (buffer.length >= MAX_BUFFER_SIZE) { // buffer大小超过最大值 OOM throw new OutOfMemoryError("Required array size too large"); } else { //当buffer的长度小于marklimit时 进行扩容 //先找到 ... -
FastDFS并发上传任务时异常:Unable to borrow buffer from pool
2019-06-19 13:46:51因需求,公司SpringBoot项目中需使用异步多线程进行FastDFS的文件上传,单个上传耗时大概1秒左右,当并发操作超过8个时总是出现Unable to borrow buffer from pool异常,小于8个时全部正常,因此怀疑是使用的... -
buffer cache 深度解析+
2012-04-19 15:46:56然后结合各个后台进程(包括DBWRn、CKPT、LGWR等)深入介绍了oracle对于buffer cache的管理机制,并详细解释了oracle为什么会采用现在的管理机制,是为了解决什么问题。比如为何会引入touch次数、为何会引入增量检查... -
android retrofit 获取post请求参数值
2017-11-24 18:07:16//请求参数值保存在requestbody中的 charset MediaType contentType = body.contentType(); if (contentType != null) { charset = contentType.charset( UTF8 ); } if ( is... -
缓冲技术之三:Linux下I/O操作buffer缓冲块使用流程
2017-11-26 22:58:20//如果不存在有效数据,将这个buffer设置为同步状态 ll_rw_block(READ, l, &bh); //如果没有有效数据,则需要现场从磁盘中将相应块号的内容读取到buffer中,这个是一个操作系统底层的操作 wait_on_buffer(bh);... -
SpringCloud-gateway全局GlobalFilter获取post的请求参数
2018-10-25 11:04:29GlobalFilter实际上还是比较常用的,譬如可以在GlobalFilter里做日志处理、认证鉴权等,这里就涉及一个获取到请求参数的问题。 用户发起Get、Post请求,经过网关gateway,gateway的GlobalFilter进行拦截——获取... -
记录spring-cloud-gateway获取post请求body参数,以及后端服务处理后的响应参数过程 gateway:2.2.0.RELEASE
2020-07-29 15:55:08介绍一下框架版本 spring-boot:2.2.1.RELEASE spring-cloud:Hoxton.RELEASE(2.2.0.RELEASE) ...之前参考京东大神的代码,挨着试了一遍,发现版本不对,已经不能用了,附上链接https://blog.csdn.net/tianya -
Linux 驱动之模块参数--Linux设备驱动程序
2016-03-31 14:26:01模块参数很多情况下,我们期望通过参数来控制我们的驱动的行为,比如由于系统的不同,而为了保证我们驱动有较好的移植性,我们有时候期望通过传递参数来控制我们驱动的行为,这样不同的系统中,驱动可能有不同的行为...